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

C#异步TCP Listener Socket无法接受连接问题求助

问题产生原因
  • 核心逻辑漏洞:Main 方法执行完 tl.BeginAcceptTcpClient(OnCompleteTCP, tl); 后没有任何阻塞逻辑,控制台应用主进程会直接终止,所有异步回调没有机会被触发,自然无法接受连接。
  • 单次监听缺陷:接受完第一个客户端连接后没有重新调用 BeginAcceptTcpClient,只能处理最多一次连接请求,后续客户端无法接入。
  • 并发资源冲突:全局声明的 TcpClient 和 byte[] Mybuffer 是共享变量,多客户端连接时会出现资源覆盖、数据串包的问题。
  • 数据解析错误:读取到指定长度的字节后直接将整个缓冲区转成字符串,会输出大量无效空字符,应该仅对实际读取到的字节长度做转换。
修复方案

按照以下逻辑调整代码即可解决问题:

  1. 为Main方法添加阻塞逻辑,避免主进程直接退出
  2. 在连接接收回调末尾重新发起异步监听,支持多客户端接入
  3. 移除全局共享的连接和缓冲区对象,每个连接使用独立资源避免并发冲突
  4. 修正字节转字符串的逻辑,仅处理实际收到的字节长度
  5. 可选优化:监听IP改为IPAddress.Any,自动适配本机所有网卡,不需要写死固定IP

修复后完整代码如下:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Program
{
    private static void PrintUsageInfo()
    {

    }
    static void Main(string[] args)
    {
        TcpListener tl = new TcpListener(IPAddress.Any, 8008);
        tl.Start();
        tl.BeginAcceptTcpClient(OnCompleteTCP, tl);
        // 阻塞主进程,防止程序直接退出
        Console.WriteLine("服务端已启动,端口8008,按任意键退出...");
        Console.ReadKey();
        tl.Stop();
    }

    static void OnCompleteReadData(IAsyncResult isa)
    {
        int countreadbytes = 0;
        // 每个连接使用独立的状态对象,避免共享冲突
        var state = (ConnectionState)isa.AsyncState;
        try
        {
            countreadbytes = state.Client.GetStream().EndRead(isa);
            if (countreadbytes == 0)
            {
                Console.WriteLine("USER Disconnected");
                state.Client.Close();
                return;
            }

            // 仅转换实际收到的字节
            Console.Write(Encoding.ASCII.GetString(state.Buffer, 0, countreadbytes));
            // 继续监听当前连接的新数据
            state.Client.GetStream().BeginRead(state.Buffer, 0, state.Buffer.Length, OnCompleteReadData, state);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            state.Client.Close();
        }
    }

    static void OnCompleteTCP(IAsyncResult isa)
    {
        TcpListener tcpl = (TcpListener)isa.AsyncState;
        try
        {
            // 重新发起监听,接收下一个客户端连接
            tcpl.BeginAcceptTcpClient(OnCompleteTCP, tcpl);
            TcpClient newClient = tcpl.EndAcceptTcpClient(isa);
            Console.WriteLine("新客户端接入");
            // 为每个新连接创建独立的缓冲区
            var state = new ConnectionState()
            {
                Client = newClient,
                Buffer = new byte[4096]
            };
            newClient.GetStream().BeginRead(state.Buffer, 0, state.Buffer.Length, OnCompleteReadData, state);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    // 自定义连接状态类,存储每个连接的独立资源
    class ConnectionState
    {
        public TcpClient Client { get; set; }
        public byte[] Buffer { get; set; }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:15:03