gpt4 book ai didi

java - Java 中的 OutputStream 是阻塞的吗? ( socket )

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:52:15 31 4
gpt4 key购买 nike

我目前正在为一个项目编写简单的网络代码,一个伙伴暗示我,当我以迭代方式从服务器向所有客户端发送一个信息包时,当其中一个客户端是没有正确回应。

他以拖钓而闻名,所以我在实现一个现在负责将数据发送到客户端的辅助线程时有点怀疑,它有一个队列,服务器只需将包添加到该队列上,然后由线程读取发送数据。

我现在思考后的问题是天气与否 Java Socket 的 OutputStream 实际上将他要发送的内容排入队列,从而无需预先排队。只有当服务器阻塞时,只要他没有收到客户端发送的对象已收到的响应,才有可能出现严重问题。

谢谢。

最佳答案

你的 friend 是对的,但更多的是关于如何协议(protocol)有效。大大简化了发送到客户端的数据包需要确认。如果客户端没有响应(无法读取传入数据、计算机负载过重等),服务器将不会收到确认并停止发送数据。这种内置于 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 中读取 - 循环会一直持续下去。

关于java - Java 中的 OutputStream 是阻塞的吗? ( socket ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10574596/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com