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

使用StreamReader/StreamWriter读取多消息遇问题:客户端仅能读取首条消息

解决StreamReader/StreamWriter多消息接收仅读取第一条的问题

你遇到的问题核心在于客户端每次循环都新建StreamReader实例,多个实例同时操作同一个NetworkStream时,它们的内部缓存会互相干扰,导致后续读取无法正确定位到流的下一个位置,最终只能拿到第一条消息。

先帮你梳理下问题细节:

  • 服务端代码是没问题的:你设置了AutoFlush = true,循环调用WriteLine会把10条"test"消息依次发送到流中,消息本身是正常输出的。
  • 客户端的问题出在WaitMessages方法里:每次进入while循环都创建新的StreamReader,而NetworkStream是连续的字节流,多个StreamReader各自维护缓存,会打乱流的读取位置,自然读不到后续消息。

修正后的客户端代码

public async Task WaitMessages() // 用async Task代替async void,更便于错误处理和调用方控制
{
    // 只创建一次StreamReader,复用它处理所有消息
    using var reader = new StreamReader(LoginChat.Client.TcpClt.GetStream());
    while (LoginChat.Client.Connected)
    {
        try
        {
            var data = await reader.ReadLineAsync();
            // 服务端断开连接时,ReadLineAsync会返回null,需要跳出循环
            if (data == null)
                break;
            MessageBox.Show(data);
        }
        catch (Exception ex)
        {
            // 这里可以添加异常日志或断开连接的处理逻辑
            break;
        }
    }
}

关键优化点说明

  1. 复用StreamReader实例:在循环外部创建一次StreamReader,用using语句确保资源会被正确释放。这样所有读取操作都基于同一个流位置和缓存,能依次读取每条消息。
  2. 替换async void为async Task:async void仅适合事件处理场景,普通方法用async Task更便于捕获异常、等待执行完成,避免异步操作的潜在问题。
  3. 处理ReadLineAsync返回null的情况:当服务端主动断开连接时,ReadLineAsync会返回null,这时候需要跳出循环,避免无限等待无效连接。

另外,服务端代码也可以优化下资源管理,用using语句确保StreamWriter被正确释放:

using var stwWriter = new StreamWriter(client.GetStream()) { AutoFlush = true };
for (int i = 0; i < 10; i++)
{
    stwWriter.WriteLine("test");
}

这样修改后,客户端就能依次接收到服务端发送的10条"test"消息了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:02:32