You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Socket中BufferedReader读取多行文本后While循环无法终止

Socket多行数据传输后服务端循环无法终止的问题分析与解决

问题现象

服务端能够正常打印客户端发送的所有文本,但while((line = in.readLine()) != null)循环始终无法终止,后续的System.out.println("is it here?")代码永远不会执行。

问题原因

BufferedReader.readLine()方法返回null的唯一触发条件是输入流到达末尾(EOF,即对方关闭了输出流)。但当前客户端发送完数据后,并没有关闭输出流,而是保持Socket连接,等待服务端返回响应(客户端代码中存在input.readLine()逻辑)。这导致服务端的输入流一直处于打开状态,readLine()会持续阻塞等待新的数据,永远不会返回null,循环也就无法终止。

解决方法

方法1:约定数据结束标记

在客户端和服务端之间约定一个特殊的结束标记,服务端读到该标记时主动终止循环。

  • 客户端修改:发送完目标数据后,额外发送结束标记
// 原发送代码
out.println(command + " 3 \n" + message);
// 添加结束标记
out.println("END_OF_TRANSMISSION");
  • 服务端修改:在循环中判断是否收到结束标记
String line = "";
while((line = in.readLine()) != null) {
    // 检测到结束标记,终止循环
    if ("END_OF_TRANSMISSION".equals(line)) {
        break;
    }
    System.out.println(line);
}
System.out.println("is it here?");

方法2:关闭客户端输出流的写方向(适用于单次请求场景)

如果客户端发送完数据后,仅需要接收服务端响应而不再发送数据,可以使用Socket.shutdownOutput()关闭输出流的写方向,这样服务端会收到EOF信号,readLine()返回null,循环终止。该操作不会关闭整个Socket,客户端仍能通过输入流读取服务端响应。

  • 客户端修改:发送完数据后调用shutdownOutput()
out.println(command + " 3 \n" + message);
// 关闭输出方向,告知服务端数据已发送完毕
socket.shutdownOutput();

服务端无需修改原循环逻辑,此时循环会在读取完所有数据后,因为输入流到达EOF而终止,执行后续代码。

内容的提问来源于stack exchange,提问作者Cecil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:45:31