0

我刚开始学习java。我修改了服务器/客户端通信程序的客户端代码,为客户端创建了两个线程,主线程用于接收用户输入,inputThread 用于接收服务器响应。我确信服务器已经向客户端发送了响应,但是,客户端没有响应消息。

这是我的代码。谁能帮我弄清楚?谢谢

package clientnio;

import java.net.*; 
import java.nio.*; 
import java.io.*;
import java.nio.channels.*; 
import java.util.Scanner; 

public class ClientNIO {
public static int bufferLen = 50;
public static SocketChannel client;
public static ByteBuffer writeBuffer;
public static ByteBuffer readBuffer;

public static void main(String[] args) { 
    writeBuffer = ByteBuffer.allocate(bufferLen);
    readBuffer = ByteBuffer.allocate(bufferLen);

    try { 
        SocketAddress address = new InetSocketAddress("localhost",5505); 
        System.out.println("Local address: "+ address);
        client=SocketChannel.open(address);
        client.configureBlocking(false); 

        //readBuffer.flip();
        new inputThread(readBuffer);

        /*
        String a="asdasdasdasddffasfas"; 
        writeBuffer.put(a.getBytes()); 
        writeBuffer.clear();  
        int d=client.write(writeBuffer);
        writeBuffer.flip();
        */

        while (true) {
            InputStream inStream = System.in;
            Scanner scan = new Scanner(inStream);
            if (scan.hasNext()==true) {
                String inputLine = scan.nextLine();
                writeBuffer.put(inputLine.getBytes()); 
                //writeBuffer.clear();
                System.out.println(writeBuffer.remaining());
                client.write(writeBuffer);
                System.out.println("Sending data: "+new String(writeBuffer.array()));
                writeBuffer.flip(); 
                Thread.sleep(300);
            }
        }                 
    } 
    catch(Exception e) { 
        System.out.println(e);
    } 

}
}

class inputThread extends Thread {
private ByteBuffer readBuffer;
public inputThread(ByteBuffer readBuffer1) {  
    System.out.println("Receiving thread starts.");
    this.readBuffer = readBuffer1;
    start();
}

@Override
public void run() {
    try {
        while (true) {
            readBuffer.flip();
            int i=ClientNIO.client.read(readBuffer); 
            if(i>0) { 
                byte[] b=readBuffer.array(); 
                System.out.println("Receiving data: "+new String(b)); 
                    //client.close(); 
                    //System.out.println("Connection closed."); 
                    //break; 
            }
            Thread.sleep(100); 
        }
    }
    catch (Exception e) {
       System.out.println(e);
    }
  }
}
4

2 回答 2

0

flip()在读取缓冲区之前调用它是错误的。不要那样做。您需要在写入之前翻转它,或者从它获取,compact()然后再翻转它。

于 2012-10-15T08:57:47.793 回答
0

免责声明:我不是 Java 的活跃用户。(我只在学校用过。)


建议:我认为如果您使用阻塞模式将大大简化调试过程,至少在您的代码示例正常工作之前。(目前您的代码似乎没有从非阻塞模式中受益。)


我已经确定了两个问题,最终导致可能需要更改的四行代码:

  1. 当 a分配它的后备数组时,它通过设置为零和该数组的容量来ByteBuffer设置自己准备写入。您的两种用法(分别在写入循环和读取循环中)似乎违反了惯例。positionlimitByteBuffer.flip()
  2. 调用该ByteBuffer.array()方法总是返回整个后备数组,因此它总是有 size bufferLen。因此,String从全尺寸数组构造的一个可能包含来自先前传输的垃圾。
    • 通常,需要将数组修剪到传输大小,并且aString和字节数组之间的转换必须使用与服务器相同的编码。

我对第一个问题的建议更改:(
注意:我不知道如何解决数组修剪和编码问题。)

writeBuffer.put(inputLine.getBytes()); 
writeBuffer.flip();                       // <--here
client.write(writeBuffer);
...
writeBuffer.clear();                      // <-- should be clear() instead of flip()
Thread.sleep(300);

// readBuffer.flip();                      // <-- remove this line
int i=ClientNIO.client.read(readBuffer); 
if(i>0) { 
    readBuffer.flip();                     // <-- move it here
    byte[] b=readBuffer.array(); 
    System.out.println("Receiving data: "+new String(b)); 
    ...
}

参考

于 2012-10-15T04:36:05.600 回答