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

Async Socket开发中ReadAsync仅首次阻塞 循环中无法接收新数据如何解决

问题根因

你当前的代码存在两个核心问题:

  • 仅调用了一次AcceptTcpClientAsync,程序只能接收单个客户端连接,完全不支持多客户端需求
  • 没有判断ReadAsync的返回值:TCP流的读取操作返回0时代表远端已经主动关闭连接,此时循环不会再阻塞等待新数据,会进入空转状态

修复方案

  1. 在外层加循环持续接收新客户端连接,每个新连接单独启动独立异步任务处理,避免单客户端阻塞新连接接入
  2. 每个客户端的处理逻辑中新增返回值判断,读取到0字节时主动释放资源退出循环
  3. 客户端相关资源用using包裹自动释放,缓冲区每个连接单独初始化避免数据冲突

修正后参考代码

private static async Task StartListener(int port)
{
    var tcpListener = TcpListener.Create(port);
    tcpListener.Start();
    Console.WriteLine("Waiting for clients...");
    // 外层死循环持续接收新连接
    while (true)
    {
        // 等待新客户端接入
        var tcpClient = await tcpListener.AcceptTcpClientAsync();
        Console.WriteLine("A Client has connected");
        // 每个客户端单独开异步任务处理,不阻塞新连接接收
        _ = ProcessClientAsync(tcpClient);
    }
}

private static async Task ProcessClientAsync(TcpClient tcpClient)
{
    // 使用using自动释放资源
    using (tcpClient)
    using (var networkStream = tcpClient.GetStream())
    {
        byte[] dataIn = new Byte[128];
        byte[] dataOut = Encoding.ASCII.GetBytes("$value=0");
        int read = 0;
        try
        {
            while (true)
            {
                read = await networkStream.ReadAsync(dataIn, 0, 128);
                // 读取到0字节说明客户端断开,退出循环
                if (read == 0)
                {
                    Console.WriteLine("Client disconnected");
                    break;
                }
                // 此处可扩展你对接收数据的自定义处理逻辑
                await networkStream.WriteAsync(dataOut, 0, dataOut.Length);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Client processing exception: {e.Message}");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:18:03