服务器端BufferedReader调用readLine()阻塞,无法读取客户端数据
解决Socket服务器端readLine()阻塞问题
看起来你遇到的是Socket通信里典型的readLine()阻塞问题——毕竟这个方法的特性就是要读到换行符(\n)或者流结束才会返回,不然就一直卡着。结合你的客户端代码片段,我给你梳理几个最可能的原因和对应的解决办法:
客户端发送的数据没有换行符
因为
BufferedReader.readLine()是严格以换行符(\n)或者回车换行(\r\n)作为结束标记的,如果你的客户端发送内容时没加这个标记,服务器端就会一直等这个结束符,自然陷入阻塞。
解决:在客户端发送的字符串末尾加上\n或者\r\n,或者直接用println()方法(自带换行),示例代码:PrintWriter out = new PrintWriter(socket.getOutputStream(), true); out.println("你要发送的内容"); // 自动追加换行符 // 或者手动添加 out.write("你要发送的内容\n");客户端输出流没有刷新缓冲区
如果你用的是带缓冲区的输出流(比如BufferedWriter或者未开启自动刷新的PrintWriter),数据可能还留在客户端的缓冲区里,根本没发送到服务器,服务器自然读不到内容而阻塞。
解决:有两种方式处理:// 方式1:创建PrintWriter时开启自动刷新(第二个参数设为true) PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 方式2:使用BufferedWriter时手动调用flush() BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write("发送内容\n"); writer.flush(); // 强制将缓冲区数据推送至服务器客户端未告知服务器数据已发送完毕(长连接/单次通信场景)
如果是单次通信场景,客户端发送完所有数据后,没有关闭输出流的写端,服务器会误以为还有数据要发送,从而一直阻塞在readLine()上。
解决:发送完数据后调用shutdownOutput(),明确告知服务器“我这边已经写完了”:socket.shutdownOutput();
另外,你也可以用抓包工具确认客户端是否真的发送了数据,以及数据格式是否符合预期,这能帮你更快定位问题。
内容的提问来源于stack exchange,提问作者swiftsword94
相关产品推荐
相关产品推荐

