2

在我的项目中,我使用DataOutputStreamandDataInputStream使用带有线程的套接字发送和接收字节。

客户

public void run(){
    while(isRunning) {//which is true upon connection of the socket to the server
         if(scanner.hasNext()){ // I use a scanner to test the program
             dos = new DataOutputStream(new OutputStream(socket.getOutputStream));

             byte[] toServer = scanner.next().getBytes();
             dos.writeInt(toServer.length);
             dos.write(toServer);
         } 
    }
}

服务器

public void run(){
    while(isRunning){
        if(scanner.hasNext()){
              dis = new DataInputStream(new InputStream(socket.getInputStream));    
              int arrLength = dis.readInt();

              byte[] fromClient = new byte[arrLength];
              dis.read(fromClient, 0, fromClient.length);
              System.out.println("Your string is: " + new String(fromClient));
        }
    }
}

问题是,当我new String(fromClient)在服务器端打印出来时,单词/句子的第一个字符总是丢失。当我在客户端输入单词"Test"时,服务器会打印出"est". 但是当我输入" Test"(开头有一个空格)时,服务器会打印出"Test". 我不明白怎么了?我的字节转换有问题吗?

4

2 回答 2

2

下面的代码对我有用。鉴于帖子中的拼写错误,我怀疑这不是正在运行的实际代码,而是一个近似值,并且这是真实代码中的错误。这里有一些东西要寻找:

  • 如果你有一个dis.readByte();after readInt()call,那显然会切断主角。确保您的写入和读取完全对称。还要确保您的流链是对称的。

  • 如果您从另一个类获取流,请确保它本身没有执行任何读取方法。

  • 当前的帖子正在做一个new InputStream()(and OutputStream),因为它们是抽象的,所以不会编译。如果那里有缓冲,则需要确保dos.flush();. 然而,这会导致挂起而不是部分输入。


String file = "/tmp/x";
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));

String inputString = "Test";
byte[] toServer = inputString.getBytes();
dos.writeInt(toServer.length);
dos.write(toServer);

DataInputStream dis = new DataInputStream(new FileInputStream(file));
int arrLength = dis.readInt();

byte[] fromClient = new byte[arrLength];
dis.read(fromClient, 0, fromClient.length);
// works fine for me
assertEquals(inputString, new String(fromClient));
于 2012-06-19T18:27:43.000 回答
0

您应该使用 readFully() 而不是 read(),并且您不应该为每次读取或写入都重新构建流。在套接字的生命周期中使用相同的流。另外扫描仪连接到什么?如果它连接到套接字,它将使用其中的数据。

于 2012-06-19T22:31:57.867 回答