基于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); }
额外优化建议
- 线程安全保障:
LbConnections是静态List<SimClient>,而AcceptCallback运行在ThreadPool线程中,多客户端并发连接时会出现线程冲突。建议用lock块保护集合操作,或者直接替换为线程安全的ConcurrentBag<SimClient>。 - 调整监听队列长度:
ServerSocket.Listen(0)中的参数代表等待连接的队列长度,0会使用系统默认值,高并发场景下建议设置合理数值(比如100),避免连接请求被丢弃。 - 客户端断开清理:当客户端断开连接(
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
相关产品推荐
相关产品推荐

