带有套接字的DataInputStream ...缺少字节?

时间:2012-06-19 16:45:12

标签: java multithreading sockets byte

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

客户端

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"。我不明白什么是错的?我的字节转换有问题吗?

2 个答案:

答案 0 :(得分:2)

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

  • 如果您在dis.readByte();电话后有readInt(),则显然会切断主角。确保您的写入和读取完全对称。还要确保您的流链是对称的。

  • 如果要从其他类获取流,请确保它本身没有执行任何读取方法。

  • 当前帖子正在执行new InputStream()(和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));

答案 1 :(得分:0)

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