在我的项目中,我使用DataOutputStream
和DataInputStream
来使用带有线程的套接字发送和接收字节。
客户端
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"
。我不明白什么是错的?我的字节转换有问题吗?
答案 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(),并且不应该为每次读取或写入重建流。在套接字的生命周期中使用相同的流。扫描仪附加的是什么?如果它连接到套接字,它将使用它的数据。