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

基于C#异步回调的TCP服务器仅支持单连接问题求助

问题诊断与修复方案

你遇到的核心问题是TCP服务器仅能处理第一个客户端连接,后续无法接受新连接——这是异步Socket编程里的典型坑点:BeginAccept是单次触发的异步操作,处理完当前连接后必须手动再次调用它,服务器才能继续监听后续的客户端请求。

具体问题根源

你的AcceptCallback方法在处理完第一个客户端的连接初始化后,没有再次调用ServerSocket.BeginAccept(AcceptCallback, ServerSocket)。这就导致服务器在完成第一个连接的处理后,直接停止了新连接的监听,后续客户端自然无法接入。

修复后的AcceptCallback代码

private static void AcceptCallback(IAsyncResult result)
{
    var listener = (Socket)result.AsyncState;
    var handler = listener.EndAccept(result);

    // 关键操作:处理完当前连接后,立即重启异步接受新连接的逻辑
    listener.BeginAccept(AcceptCallback, listener);

    var state = new StateObject();
    state.WorkSocket = handler;
    // 注意:List<SimClient>非线程安全,多线程添加时必须加锁
    lock(LbConnections)
    {
        LbConnections.Add(new SimClient { State = state });
    }

    handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, SocketFlags.None, ReceiveCallback, state);
}

额外优化建议

  1. 线程安全保障:LbConnections是静态List<SimClient>,而AcceptCallback运行在ThreadPool线程中,多客户端并发连接时会出现线程冲突。建议用lock块保护集合操作,或者直接替换为线程安全的ConcurrentBag<SimClient>。
  2. 调整监听队列长度:ServerSocket.Listen(0)中的参数代表等待连接的队列长度,0会使用系统默认值,高并发场景下建议设置合理数值(比如100),避免连接请求被丢弃。
  3. 客户端断开清理:当客户端断开连接(received <= 0时),需要从LbConnections中移除对应客户端并关闭Socket,防止内存泄漏。修改后的断开处理逻辑示例:
if (received <= 0)
{
    // 移除连接并释放Socket资源
    lock(LbConnections)
    {
        var clientToRemove = LbConnections.FirstOrDefault(c => c.State.WorkSocket == socket);
        if(clientToRemove != null)
        {
            LbConnections.Remove(clientToRemove);
        }
    }
    socket.Close();
    return;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:02:55