C#中SimpleTCP服务器无法停止监听本地IP问题求助
问题排查与解决方案
1. 确保SimpleTcpServer实例引用唯一
如果每次调用ServerOnline都新建SimpleTcpServer实例,后续ServerOffline操作的会是旧的失效实例,自然停不掉。修正代码如下:
// TCP-Control.cs private SimpleTcpServer _tcpServer; public void ServerOnline() { if (_tcpServer == null) { _tcpServer = new SimpleTcpServer("0.0.0.0", 你的端口号); // 绑定连接、接收等回调逻辑 } if (!_tcpServer.IsListening) _tcpServer.Start(); } public void ServerOffline() { if (_tcpServer != null && _tcpServer.IsListening) { _tcpServer.Stop(); _tcpServer.Dispose(); _tcpServer = null; } }
2. 解决跨线程UI操作阻塞
WinForm中如果SimpleTcpServer的回调事件(如客户端连接、数据接收)直接操作UI控件,会触发跨线程异常,导致Stop()执行被阻塞。所有UI操作必须切换到UI线程:
// TCP-Control中回调更新UI的示例 private void OnClientConnected(object sender, ClientConnectedEventArgs e) { Form1.Instance.Invoke((Action)(() => { Form1.Instance.txtLog.Text += $"客户端 {e.IpPort} 连接\n"; })); }
3. 先断开所有活跃客户端再停止服务器
部分SimpleTcpServer实现需要先断开所有连接,否则未关闭的客户端连接会占用端口。修改停止逻辑:
public void ServerOffline() { if (_tcpServer != null && _tcpServer.IsListening) { // 遍历断开所有客户端 foreach (var client in _tcpServer.GetClients()) { client.Disconnect(); } // 短延迟确保连接断开 System.Threading.Thread.Sleep(100); _tcpServer.Stop(); _tcpServer.Dispose(); _tcpServer = null; } }
4. 加锁避免多线程竞态问题
如果启动/停止操作可能被多线程调用,加锁保证操作原子性:
private readonly object _serverLock = new object(); public void ServerOnline() { lock (_serverLock) { // 启动逻辑 } } public void ServerOffline() { lock (_serverLock) { // 停止逻辑 } }
5. 强制释放底层Socket资源(针对第三方库bug)
如果SimpleTcpServer的Stop()未正确释放Socket,手动强制关闭:
public void ServerOffline() { if (_tcpServer != null && _tcpServer.IsListening) { _tcpServer.Stop(); // 假设库暴露了底层Socket属性 _tcpServer.ServerSocket.Shutdown(SocketShutdown.Both); _tcpServer.ServerSocket.Close(); _tcpServer.Dispose(); _tcpServer = null; } }
验证步骤
- 在
ServerOffline末尾打印_tcpServer?.IsListening,确认状态是否为false - 执行
netstat -ano | findstr :你的端口号,检查端口是否还被当前进程占用 - 在
ServerOffline中加入日志,确认方法确实被执行到
内容的提问来源于stack exchange,提问作者Vraces
相关产品推荐
相关产品推荐

