你的朋友是对的,但它与tcpip协议的工作原理有更多关系。需要确认发送到客户端的数据包在很大程度上简化。如果客户端没有响应(无法读取传入的数据,计算机负载过重等),服务器将不会收到确认,并将停止发送数据。TCP/IP 中内置的此机制可防止通信的一端发送大量数据,而无需确保另一端收到这些数据。反过来,这又避免了重新发送大量数据的要求。
在 Java 中,这表现为阻塞写入 。底层 TCP/IP 堆栈/操作系统不允许发送更多数据,直到客户端准备好接收这些数据。OutputStream
您可以轻松测试!我实现了接受连接但无法读取传入数据的简单服务器:
new Thread(new Runnable() {
@Override
public void run() {
try {
final ServerSocket serverSocket = new ServerSocket(4444);
final Socket clientSocket = serverSocket.accept();
final InputStream inputStream = clientSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
还有一个简单的客户端,只需在 4K 批处理中发送尽可能多的数据:
final Socket client = new Socket("localhost", 4444);
final OutputStream outputStream = client.getOutputStream();
int packet = 0;
while(true) {
System.out.println(++packet);
outputStream.write(new byte[1024 * 4]);
}
客户端循环在 95 次迭代后挂起在我的计算机上(您的里程可能会有所不同)。但是,如果我从服务器线程中读取 - 循环会继续。inputStream