Java客户端无法接收C#服务端TCP响应问题求助
Java与C# TCP通信客户端无法接收响应问题分析
问题概述
首次尝试实现Java客户端与C#服务端的TCP通信,客户端发送消息后服务端能接收并返回响应,但客户端始终无法收到服务端的响应,需分析问题原因及修复方案。
C#服务端代码
public void CreateServer() { Thread thread = new Thread(() => { IPAddress addr = IPAddress.Parse(localIP); tcpListener = new TcpListener(addr, 5053); if (tcpListener != null) { tcpListener.Start(); while (!end) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); var ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString(); Console.WriteLine("Client connected from "+ip); NetworkStream clientStream = tcpClient.GetStream(); StreamReader reader = new StreamReader(clientStream, Encoding.UTF8); try { string request = reader.ReadToEnd(); Console.WriteLine("Message from client: " + request); Byte[] StringToSend = Encoding.UTF8.GetBytes("Server"); clientStream.Write(StringToSend, 0, StringToSend.Length); Console.WriteLine("Sending response back"); } catch (Exception e) { Console.WriteLine(e); } } } }); thread.Start(); }
Java客户端代码
public class TCP { private String IP; private InetAddress server; private Socket socket; public TCP(String IP) { this.IP = IP; } protected void runTCP() { try { server = InetAddress.getByName(IP); socket = new Socket(server, 5053); System.out.println("Client connected. Listening on port 5053"); } catch (Exception e) { e.printStackTrace(); } } public void sendMessage(String message) { try { System.out.println("Sending data..."); if (socket.isClosed()) socket = new Socket(server, 5053); PrintWriter writer = new PrintWriter(socket.getOutputStream()); writer.print(message); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } public void getResponseServer() { Thread thread = new Thread() { @Override public void run() { try { System.out.println("Attempting to get response..."); if (socket.isClosed()) socket = new Socket(server, 5053); BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); String mServerMessage = mBufferIn.readLine(); System.out.println("Server message: " + mServerMessage); } catch (Exception e) {e.printStackTrace();} } }; thread.start(); } }
运行现象
- 服务端输出:
Client connected from 192.16.... Message from client: Hello Sending response back Client connected from 192.16.... - 客户端输出:
Client connected. Listening on port 5053 Sending data... Attempting to get response... - 客户端始终无法收到服务端的响应。
问题原因分析
客户端发送消息后关闭Socket连接:Java客户端
sendMessage方法中调用writer.close(),这会直接关闭Socket的输出流,进而导致整个Socket连接被关闭。当getResponseServer方法尝试读取响应时,原连接已失效,代码中新建的Socket是一个全新的连接,而服务端的响应是发送给第一次建立的连接,新连接自然收不到。服务端
ReadToEnd()的阻塞逻辑:C#的StreamReader.ReadToEnd()会一直阻塞,直到检测到流的末尾(即客户端关闭输出流或Socket)。这也是服务端能收到"Hello"的原因——客户端关闭输出流触发了ReadToEnd()返回,但此时原连接已关闭,服务端发送的响应无法到达客户端。客户端读取响应的阻塞问题:服务端发送的响应"Server"没有换行符,而客户端使用
BufferedReader.readLine()读取,该方法会一直阻塞直到读到换行符或流结束。即使新建Socket,服务端也未给这个新连接发送数据,导致读取操作一直卡着。
修复方案
客户端修改
- 保留Socket连接,不关闭PrintWriter:移除
sendMessage中的writer.close(),仅保留flush(),避免关闭Socket连接,同时给发送的消息添加换行符,适配服务端的读取逻辑:
public void sendMessage(String message) { try { System.out.println("Sending data..."); if (socket.isClosed()) socket = new Socket(server, 5053); PrintWriter writer = new PrintWriter(socket.getOutputStream()); writer.print(message + "\n"); writer.flush(); // 不要关闭writer,避免关闭Socket } catch (IOException e) { e.printStackTrace(); } }
服务端修改
- 改用
ReadLine()读取消息:替换ReadToEnd()为ReadLine(),配合客户端发送的换行符完成读取,同时给响应添加换行符,适配客户端的readLine():
try { string request = reader.ReadLine(); Console.WriteLine("Message from client: " + request); Byte[] StringToSend = Encoding.UTF8.GetBytes("Server\n"); clientStream.Write(StringToSend, 0, StringToSend.Length); Console.WriteLine("Sending response back"); } catch (Exception e) { Console.WriteLine(e); }
客户端读取逻辑优化
- 确保使用同一个Socket读取响应:移除
getResponseServer中新建Socket的逻辑,直接使用已建立的连接读取:
public void getResponseServer() { Thread thread = new Thread() { @Override public void run() { try { System.out.println("Attempting to get response..."); BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); String mServerMessage = mBufferIn.readLine(); System.out.println("Server message: " + mServerMessage); } catch (Exception e) {e.printStackTrace();} } }; thread.start(); }
内容的提问来源于stack exchange,提问作者lukaking98
相关产品推荐
相关产品推荐

