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
相关产品推荐
相关产品推荐

