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

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;
    }
}

验证步骤

  1. 在ServerOffline末尾打印_tcpServer?.IsListening,确认状态是否为false
  2. 执行netstat -ano | findstr :你的端口号,检查端口是否还被当前进程占用
  3. 在ServerOffline中加入日志,确认方法确实被执行到

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:10:24