您的朋友是对的,但它更多地与tcpip协议的工作方式有关。大大简化了发送到客户端的数据包需要确认。如果客户端没有响应(无法读取传入的数据,计算机负载过重等),服务器将不会收到确认并停止发送数据。TCP/IP 中内置的这一机制可防止通信的一端发送大量数据,而无需确保另一端接收到这些数据。反过来,这避免了重新发送大量数据的要求。
在 Java 中,这表现为阻塞写入OutputStream
. 在客户端准备好接收数据之前,底层 TCP/IP 堆栈/操作系统不允许发送更多数据。
你可以很容易地测试这个!我实现了接受连接但无法读取传入数据的简单服务器:
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
服务器线程中读取-循环继续进行。