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

C#使用StreamReader读取服务端返回字符串时出现截断不完整问题

C# TcpClient响应读取不完整问题修复方案

问题根因

  • TCP是面向流的传输协议,本身不存在消息边界,StreamReader.ReadLine() 的返回触发条件为:接收到换行符、输入流关闭、内部缓冲区填满。你遇到的偶发截断是因为单次网络传输仅返回了部分响应数据,未携带完整的换行符,导致ReadLine()提前返回不完整内容,该场景不属于异常,因此不会进入你预设的catch处理逻辑。
  • 现有实现的资源管理不规范,每次循环新建/销毁TcpClient连接,频繁的TCP握手挥手容易引发网络波动,也会提升传输异常的概率。

修复方案

前提约定

首先确认服务端的响应规则:如果服务端是短连接模式(返回响应后主动关闭连接),可直接用ReadToEnd()读取完整响应;如果是长连接模式,需确认响应的结束标识(固定换行符/长度前缀),下面的示例基于最常见的「短连接+响应末尾带换行」的场景优化:

using System; 
using System.IO; 
using System.Net.Sockets;
using System.Text.RegularExpressions;

// 正则复用,不要在循环内重复实例化
private static readonly Regex _numRegex = new Regex(@"\d+", RegexOptions.Compiled);
// 重试次数限制,避免无限重试
private const int MaxRetryCount = 3;

public static void Request1(int start, int end)
{
    for (int i = start; i <= end; i++)
    {
        int retryCount = 0;
        bool success = false;
        while (retryCount < MaxRetryCount && !success)
        {
            try
            {
                // using块自动释放资源,无需手动调用Close
                using TcpClient client = new TcpClient();
                client.Connect(server, port);
                // 设置读写超时,避免无限等待
                client.ReceiveTimeout = 5000;
                client.SendTimeout = 5000;

                using NetworkStream stream = client.GetStream();
                using StreamWriter writer = new StreamWriter(stream);
                using StreamReader reader = new StreamReader(stream);
                
                // 发送请求
                string request = i.ToString() + "\n";
                writer.WriteLine(request);
                writer.Flush();

                // 读取完整响应,短连接场景下服务端返回后会关连接,ReadToEnd会拿到所有返回内容
                string message = reader.ReadToEnd().Trim();
                
                // 校验响应有效性
                if (string.IsNullOrEmpty(message))
                {
                    throw new InvalidDataException("响应为空");
                }

                Match match = _numRegex.Match(message);
                if (!match.Success)
                {
                    throw new InvalidDataException("未匹配到有效数字");
                }

                int result = Convert.ToInt32(match.Value);
                Console.WriteLine($"Number {i}: {result}");
                numList[i] = result;
                File.AppendAllText("File2.txt", $"Number {i}: {result}\n");
                success = true;
            }
            catch (Exception ex)
            {
                retryCount++;
                Console.WriteLine($"Number {i} 处理失败,第{retryCount}次重试,异常信息:{ex.Message}");
                if (retryCount >= MaxRetryCount)
                {
                    Console.WriteLine($"Number {i} 已达到最大重试次数,跳过处理");
                    // 这里可根据业务需求决定是跳过还是抛出异常
                }
            }
        }
    }
}

额外优化建议

  • 如果服务端是长连接模式,不要使用ReadToEnd(),改为循环读取直到拿到约定的结束标识(比如完整的换行符)。
  • 频繁调用File.AppendAllText性能较低,可改为批量写入或者使用持久化的StreamWriter实例写文件。
  • 若并发量较高,建议复用TcpClient连接,避免频繁建立销毁连接的开销。

内容的提问来源于stack exchange,提问作者magrega

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:39:03