Java ServerSocket 的客户端不/不一致地接收给定数量的字节

问题描述 投票:0回答:0

当我尝试通过 Java ServerSocket 通过网络发送图像(它是字节)和一些其他数据时,我发现代码中存在一个有趣的不一致。

我多次运行相同的服务器和客户端代码,有时它们都死锁了(因为它们之间的协议比发送图像更复杂),有时它们运行良好。

在越来越简化之后,我发现这些程序会有不同的结果,这取决于我在服务器端的 2 条指令之间放置的延迟:

服务器主要方法:

ServerSocket serverSocket = new ServerSocket(4999);
Socket clientSocket = serverSocket.accept();
        
OutputStream outStream = clientSocket.getOutputStream();
PrintWriter outWriter = new PrintWriter(outStream, true);
        
byte buf[] = new byte[2000];
        
System.out.println("sending: " + buf.length + " bytes");

outWriter.println(buf.length);
// If I put a delay here, for example 1000 System.out.println(1) statements, the client receives the buffer correctly, if not the client receives 0 bytes
outStream.write(buf);

clientSocket.close();
serverSocket.close();

客户端主要方法:

Socket clientSocket = new Socket(InetAddress.getByName("<address of the server>"), 4999);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

int len = Integer.valueOf(in.readLine());
System.out.println("expected length: " + len);
        
byte[] receiveBuf = clientSocket.getInputStream().readNBytes(len);
System.out.println("received buffer length: " + receiveBuf.length);
// at this point, the receiveBuf.length should be the expected size,
// but as soon as the server sends a to large buffer, the client
// prints that it received 0 bytes. With a buffer size of 20000 bytes
// I got the client to output that it received 11808 bytes, which is 20000 - 2^13...
        
clientSocket.close();

现在我的问题是,(如果我研究正确的话)这个事务使用 TCP/IP,这意味着与 UDP 相比,数据应该始终正确发送和接收,无论设备有多慢或多快,或者如何你在指令之间放置了很多延迟。 但是,尽管客户端确实收到了正确的缓冲区长度(客户端第 4 行),但它收到的缓冲区长度小于预期大小(由客户端第 8 行输出),一旦服务器发送的数组太长(在我的例子中:大小 > 1443 字节)。

我不得不提的事情:服务器必须发送的确切字节数,以便客户端说它收到零字节可能会随着客户端速度(慢Pc,快Pc)而变化,但2000字节应该已经足够了(这样我就可以在我拥有的每台设备(笔记本电脑、虚拟机、个人电脑)上重现它)。如果服务器和客户端是同一台设备,则不会出现该错误!

所以我的问题是:这个 TCP 事务的结果(和完整性)如何取决于服务器站点上程序的执行速度?

PS:这里所说的执行速度,是指在服务器程序中可选的添加System.out.println()语句,它以某种方式决定客户端是否成功接收缓冲区。

java tcp ip serversocket
© www.soinside.com 2019 - 2024. All rights reserved.