Java持久化TCP连接问题:客户端服务器二次通信无响应求助
问题分析与修复方案
嘿,我来帮你搞定这个TCP通信的问题!你的代码第一次通信正常,但第二次请求无响应的核心原因是服务器端的逻辑错误——它只处理了客户端的第一次请求,就回到等待新连接的状态,完全没管同一个连接的后续请求。
问题根源拆解
服务器的外层while(true)是用来监听新客户端连接的,但每次通过ss.accept()拿到客户端Socket后,你只执行了一次in.readLine()和out.writeBytes(),然后就直接回到外层循环等待下一个客户端了。这就导致:
- 第一个客户端的连接在第一次通信后,服务器就不再监听它的后续数据
- 客户端还在同一个连接上发送第二次请求,服务器根本没接收,客户端自然就挂起等待响应了
修复方案
我们需要让服务器在接受一个客户端连接后,持续处理该连接上的所有请求,直到客户端主动断开。同时优化客户端的小细节,提升代码效率。
修复后的服务器代码
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String args[]) throws IOException{ ServerSocket ss = new ServerSocket(81); System.out.println("server started"); while(true){ System.out.println("waiting for client"); Socket s = ss.accept(); System.out.println("connected to client"); // 为每个客户端连接创建单独的输入输出流 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); DataOutputStream out = new DataOutputStream(s.getOutputStream()); // 内层循环:持续处理该客户端的所有请求,直到连接断开 try { String clientMsg; while ((clientMsg = in.readLine()) != null) { System.out.println("recieved: " + clientMsg); // 发送响应并立即刷新缓冲区,确保客户端能及时收到 out.writeBytes("200\n"); out.flush(); } } catch (IOException e) { // 客户端断开连接时会抛出异常,这里处理关闭逻辑 System.out.println("client disconnected"); } finally { // 关闭资源 s.close(); in.close(); out.close(); } } } }
优化后的客户端代码
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class Client { public static void main(String[] args) throws UnknownHostException, IOException { Socket clientSocket = new Socket("localhost", 81); DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); System.out.println("connected to server"); // 把Scanner移到循环外,避免重复创建对象 Scanner sc = new Scanner(System.in); while (true) { System.out.println("enter data to send"); String msg = sc.nextLine(); // 发送请求并刷新缓冲区 out.writeBytes(msg + "\n"); out.flush(); // 接收响应 String response = in.readLine(); if (response == null) { // 服务器断开连接时退出循环 System.out.println("server disconnected"); break; } System.out.println("response from server : " + response); } // 关闭资源 sc.close(); clientSocket.close(); in.close(); out.close(); } }
关键改动说明
- 服务器端:
- 添加内层
while循环,通过in.readLine()持续读取客户端的请求,直到客户端断开(readLine()返回null) - 增加异常捕获,处理客户端断开时的IO异常,确保资源能正确关闭
- 每次发送响应后调用
out.flush(),强制把缓冲区的数据发送出去,避免数据滞留
- 添加内层
- 客户端:
- 将
Scanner的创建移到循环外部,避免每次循环都创建新对象,提升性能 - 增加对
in.readLine()返回null的判断,处理服务器断开的情况,避免无限等待
- 将
现在运行修复后的代码,你就可以在同一个连接上持续发送请求和接收响应啦!
内容的提问来源于stack exchange,提问作者Shubham Singh
相关产品推荐
相关产品推荐

