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

TcpListener/TcpClient异步代码循环后后续逻辑无法执行求助

问题原因及解决方案

核心问题

  1. TCP流阻塞死锁:TCP协议中,ReadAsync返回0仅当对方主动关闭连接的输出流。当前客户端发送完数据后未关闭输出流,服务器会一直等待更多输入,卡在while循环;服务器同理未关闭输出流,客户端也会卡在读取循环,双方都无法执行循环后的代码。
  2. async void Main导致主线程提前退出:控制台程序使用async void Main时,主线程不会等待异步操作完成就直接终止,这也是程序提前结束的原因之一。

修复步骤

  1. 将Main函数改为async Task:C# 7.1及以上版本支持async Task Main,能让主线程等待异步操作完成。
  2. 客户端发送完数据后关闭输出流:告知服务器数据已发送完毕,触发服务器的ReadAsync返回0,退出循环。
  3. 服务器处理完数据后关闭输出流:告知客户端响应已发送完毕,触发客户端的ReadAsync返回0,退出循环。

修改后的代码

客户端代码

public static async Task Main()
{       
    using TcpClient client = new TcpClient("localhost", 50000);
    using NetworkStream stream = client.GetStream();
    byte[] data = RandomNumberGenerator.GetBytes(100000);
    await stream.WriteAsync(data, 0, data.Length);
    
    // 关闭输出流,通知服务器数据已发送完成
    client.Client.Shutdown(SocketShutdown.Send);
    
    byte[] bytes = new byte[8096];
    int i;
    while((i = await stream.ReadAsync(bytes, 0, bytes.Length)) > 0)
    {
        Console.WriteLine(i);
    }
    Console.WriteLine("this doesnt get printed");
    return;
}

服务器代码

public static async Task Main()
{               
    try
    {   
        TcpListener server = new TcpListener(IPAddress.Any, 50000);
        server.Start();
        using TcpClient client = await server.AcceptTcpClientAsync();
        using NetworkStream stream = client.GetStream();
        byte[] bytes = new byte[8096];
        byte[] return_bytes = new byte[8096];
        int i;
        while((i = await stream.ReadAsync(bytes, 0, bytes.Length)) > 0)
        {
            await stream.WriteAsync(return_bytes, 0, return_bytes.Length);
        }
        
        // 关闭输出流,通知客户端响应已发送完成
        client.Client.Shutdown(SocketShutdown.Send);
        
        Console.WriteLine("this doesn't get printed");
        server.Stop();
    }
    catch(Exception ex)
    {
        Console.WriteLine("port already in use");
    }
}

额外说明

  • using块会自动释放TcpClient和NetworkStream资源,无需手动调用Close()。
  • SocketShutdown.Send仅关闭输出方向的流,输入方向仍可读取数据,确保双方能完成最后的响应读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:05:16