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

.NET Framework双端口监听异常:Task.WhenAny阻塞问题求助

问题分析与解决方案

这个问题的核心原因是在.NET Framework中,TcpListener的异步接受方法(比如AcceptSocketAsync)不支持同时存在多个挂起的接受操作,而你的代码每次循环都会给所有Listener重新发起一次接受请求,导致未完成的旧请求和新请求冲突,最终使得后续的端口连接无响应。而.NET Core对TcpListener的实现做了优化,允许这种模式,所以在Core下能正常工作。

你的代码哪里出了问题?

看你的AcceptAnyConnection方法,每次调用时都会给每个TcpListener创建一个新的AcceptConnection任务(也就是发起一次新的AcceptSocketAsync请求)。当第一个端口(比如6060)被连接后,另一个Listener(6061)的AcceptSocketAsync任务其实还在后台等待连接,但下一次循环你又给6061的Listener发起了新的AcceptSocketAsync请求——在.NET Framework里,同一个TcpListener实例同时只能有一个挂起的接受操作,新的请求会干扰甚至覆盖旧的,导致后续对6061端口的连接无法被正确处理。

修复后的代码示例

正确的做法是为每个TcpListener单独启动一个持续的接受循环,让每个Listener独立处理自己端口的连接,避免请求冲突:

static void Main(string[] args)
{
    IPAddress hostIP = Dns.GetHostAddresses("127.0.0.1")[0];
    List<TcpListener> listeners = new List<TcpListener>() 
    { 
        new TcpListener(hostIP, 6060), 
        new TcpListener(hostIP, 6061) 
    };

    try
    {
        foreach (TcpListener listener in listeners)
        {
            listener.Start();
            // 为每个Listener启动独立的接受循环
            _ = HandleListenerAsync(listener);
        }

        // 保持主线程运行,避免程序直接退出
        Console.WriteLine("服务器已启动,按任意键退出...");
        Console.ReadKey();
    }
    finally
    {
        foreach (TcpListener listener in listeners)
        {
            listener.Stop();
        }
    }
}

private static async Task HandleListenerAsync(TcpListener listener)
{
    try
    {
        while (true)
        {
            Socket socket = await listener.AcceptSocketAsync();
            // 后台处理连接,不阻塞当前Listener的接受循环
            _ = HandleConnectionAsync(socket);
        }
    }
    catch (SocketException)
    {
        // Listener被Stop时会抛出异常,这里可以做日志或忽略
        Console.WriteLine($"Listener {listener.LocalEndpoint} 已停止");
    }
}

private static async Task HandleConnectionAsync(Socket socket)
{
    try
    {
        using (NetworkStream stream = new NetworkStream(socket))
        {
            byte[] bytes = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
            await stream.WriteAsync(bytes, 0, bytes.Length);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"处理连接时出错: {ex.Message}");
    }
    finally
    {
        socket.Close();
    }
}

关键修改点说明

  1. 独立的Listener循环:每个TcpListener有自己的HandleListenerAsync循环,持续监听自身端口,不会和其他Listener的接受操作冲突。
  2. 后台处理连接:用_ = HandleConnectionAsync(socket)让连接处理在后台异步执行,避免阻塞当前Listener的接受流程,保证新连接能被及时响应。
  3. 主线程保持存活:通过Console.ReadKey()让主线程持续运行,防止程序启动后直接退出。
  4. 异常处理:添加了针对Listener停止和连接处理的异常捕获,让程序更健壮。

这种模式在.NET Framework和.NET Core下都能稳定工作,彻底解决了端口无响应的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:59:30