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

Unity中C# TCP Server如何用布尔值手动终止线程

解决方案

要实现通过布尔值自然终止TCP服务器线程,核心是解决AcceptTcpClient()的阻塞问题——原代码中这个方法会一直卡住直到有客户端连接,导致设置keepServerAlive = false后线程无法及时退出。以下是修改后的完整代码和关键说明:

修改后的OnClientDataReceived方法

private static void OnClientDataReceived(){
    try {
        UnityEngine.Debug.Log("[TCP] Inside the try");

        // 外层循环:持续监听直到keepServerAlive为false
        while (keepServerAlive){
            UnityEngine.Debug.Log("[TCP] Inside the keep server alive");

            // 先检查是否有客户端等待连接,避免AcceptTcpClient阻塞
            if (serverSocket.Pending()){
                using (var client = serverSocket.AcceptTcpClient()) {                
                    UnityEngine.Debug.Log("[TCP] Inside the accept TCP Client");
                    
                    // 获取流并处理数据
                    using (var stream = client.GetStream()) {                   
                        int length;                   
                        UnityEngine.Debug.Log("[TCP] Inside the Get Stream");

                        // 读取数据循环:同时检查是否要终止
                        while (keepServerAlive && stream.DataAvailable) { 
                            length = stream.Read(RxBuffer, 0, RxBuffer.Length);
                            if(length <= 0) break;
                            
                            connectionStatus = ConnectionStatus.CONNECTED;
                            UnityEngine.Debug.Log("[TCP] Received " + length + " bytes");
                            comm.dataReceived(length);                     
                        }             

                        UnityEngine.Debug.Log("[TCP] After the while in the stream read");   
                    }             
                }
            } else {
                // 没有客户端连接时,短暂休眠避免占用过高CPU,同时给线程机会检查终止信号
                Thread.Sleep(100);
            }
        }

        // 关闭服务器Socket,释放资源
        serverSocket.Stop();
        VMLog.log("TCP Listening stopped naturally");
        connectionStatus = ConnectionStatus.NOT_CONNECTED;
        comm.rxThreadIsDone();

    } catch (Exception e){
        // 捕获Socket关闭时的异常,属于正常终止流程
        if(!keepServerAlive){
            VMLog.log("TCP Listening stopped via keepServerAlive flag");
        } else {
            VMLog.error("Listening thread died. Reason: " + e.Message);
        }
        connectionStatus = ConnectionStatus.NOT_CONNECTED;
        comm.rxThreadIsDone();
    }
}

关键修改点说明

  • 解决AcceptTcpClient阻塞问题:用serverSocket.Pending()先判断是否有客户端等待连接,没有则短暂休眠,这样线程能定期检查keepServerAlive状态,不会一直卡在阻塞调用上。
  • 移除强制终止逻辑:删掉原代码中处理完单个客户端后设置keepServerAlive = false的代码,让服务器可以持续接受多个客户端连接,直到主动设置终止标志。
  • 流读取循环优化:在读取数据的循环中,同时检查keepServerAlive和stream.DataAvailable,确保收到终止信号时能及时退出读取流程。
  • 主动关闭Socket:在外层循环退出后调用serverSocket.Stop(),彻底释放服务器资源,同时确保任何未完成的阻塞调用能被中断。

终止服务器的方式

只需要在其他地方设置keepServerAlive = false,线程就会在下一次循环检查时自然退出,无需调用Thread.Abort()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:34:52