You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:54:21