C# 同设备TcpListener服务端与TcpClient客户端通信超时问题咨询
问题根因
- 服务端发送逻辑存在变量错误:代码中定义了响应内容
string response = "Test response";,但调用socket.Send()时传入的是未定义的data变量,实际没有把响应内容转为字节数组发送,部分编译环境下会默认发送空内容或者异常数据。 - 客户端
ReadToEnd()方法的机制问题:StreamReader.ReadToEnd()需要读取到流的结束标记(EOF)才会返回,而你的服务端发送完响应后没有主动关闭Socket连接,客户端会一直等待直到触发超时异常。你用浏览器能正常拿到响应是因为浏览器单次请求完成后服务端会主动断开连接,符合ReadToEnd()的终止条件。 - 额外的隐性问题:两端编码不统一,服务端接收用ASCII、客户端发送用UTF8,服务端发送如果没显式指定编码也会和客户端的UTF8解码逻辑不匹配,后期传输中文会出现乱码。
修复方案
服务端修改点
while (true) { // Accept a new connection Socket socket = socketListener.AcceptSocket(); if (socket.Connected) { Console.WriteLine("\nClient Connected!!\n==================\nClient IP {0}\n", socket.RemoteEndPoint); // 修复1:获取实际接收的字节长度,避免转换字符串出现多余空字符 byte[] receive = new byte[1024]; int receiveLen = socket.Receive(receive, receive.Length, 0); // 统一用UTF8编码 string buffer = Encoding.UTF8.GetString(receive, 0, receiveLen); string response = "Test response"; // 修复2:把响应内容转为UTF8字节数组,修正变量名错误 byte[] data = Encoding.UTF8.GetBytes(response); int numBytes = 0; try { if (socket.Connected) { if ((numBytes = socket.Send(data, data.Length, 0)) == -1) Console.WriteLine("Socket Error: cannot send packet"); else Console.WriteLine("No. of bytes sent {0}", numBytes); } else { Console.WriteLine("Connection Dropped..."); } } catch (Exception e) { Console.WriteLine("An exception has occurred: " + e.ToString()); } // 修复3:发送完成后主动关闭Socket,触发客户端的流结束标记 socket.Shutdown(SocketShutdown.Both); socket.Close(); } }
客户端可选优化(长连接场景)
如果是短连接场景直接使用修改后的服务端即可正常运行。如果需要实现长连接,不要使用ReadToEnd(),改为约定通信协议:先读取固定长度的包头拿到实际响应的字节长度,再读取对应长度的内容即可。
内容的提问来源于stack exchange,提问作者zai-turner
相关产品推荐
相关产品推荐

