C#中如何在TCP Socket Server中使用StreamReader?
TCP Socket服务端使用StreamReader的问题解决
一、StreamReader.ReadLine()读不到内容的原因及解决
StreamReader.ReadLine()会一直阻塞,直到读取到**换行符(\n或\r\n)**或者流结束。如果你的客户端发送消息时没有附加换行符,服务端就会一直卡在ReadLine()这里,看起来像是没读到内容。
解决方法:
- 让客户端发送消息时结尾加上
\r\n(比如客户端用WriteLine而不是Write发送); - 如果无法修改客户端,改用
StreamReader.ReadToEnd()(仅适合一次性读取所有内容,长连接场景不适用),或者直接操作底层流读取指定长度的字节。
二、客户端断开后循环无法终止的问题
client.Connected属性不可靠——它只是反映最后一次IO操作时的连接状态,不会主动检测远端是否断开。真正判断连接断开的依据是:
- 调用
Stream.Read()时返回0,表示远端已主动关闭连接; - 读取时抛出
IOException(比如连接被强制重置)。
修改后的代码示例
1. 正确使用StreamReader的版本
确保客户端发送带换行符的消息:
using System; using System.Net; using System.Net.Sockets; using System.IO; class TcpServer { static void Main() { var server = new TcpListener(IPAddress.Any, 5125); server.Start(); Console.WriteLine("等待客户端连接..."); using (var client = server.AcceptTcpClient()) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream)) { Console.WriteLine("客户端已连接"); string line; try { // ReadLine会在流关闭时返回null while ((line = reader.ReadLine()) != null) { Console.WriteLine($"收到消息: {line}"); } } catch (IOException ex) { Console.WriteLine($"连接异常: {ex.Message}"); } Console.WriteLine("客户端已断开"); } server.Stop(); } }
注意:给TcpClient、Stream、StreamReader加上using语句,确保资源自动释放,避免内存泄漏。
2. 使用原始流读取的可靠版本
如果不需要按行读取,直接操作字节流更灵活:
using System; using System.Net; using System.Net.Sockets; using System.Text; class TcpServer { static void Main() { var server = new TcpListener(IPAddress.Any, 5125); server.Start(); Console.WriteLine("等待客户端连接..."); using (var client = server.AcceptTcpClient()) using (var stream = client.GetStream()) { Console.WriteLine("客户端已连接"); byte[] buffer = new byte[1024]; int bytesRead; try { // Read返回0表示连接已关闭 while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { string message = Encoding.UTF8.GetString(buffer, 0, bytesRead); Console.WriteLine($"收到消息: {message}"); } } catch (IOException ex) { Console.WriteLine($"连接异常断开: {ex.Message}"); } Console.WriteLine("客户端已断开"); } server.Stop(); } }
关键注意事项
- 所有实现
IDisposable的对象必须用using包裹,确保资源及时释放; - 绝对不要依赖
client.Connected判断连接状态,必须通过Read的返回值或异常来检测; - 使用
StreamReader时,必须保证消息结尾带有换行符,否则会一直阻塞等待。
内容的提问来源于stack exchange,提问作者killax
相关产品推荐
相关产品推荐

