Unity多人游戏关闭服务器报UdpClient已释放错误如何修复
修复方案
问题根因
调用服务器Stop()方法时,udpListener被直接释放,但此时仍有未执行完成的UDP异步接收回调,回调触发时访问已销毁的UdpClient实例就会抛出该错误。
具体修改步骤
- 新增服务器运行状态标识
在Server类的静态变量区域添加如下代码:
private static bool isServerRunning = false;
- 修改
Start()方法
在服务器启动逻辑末尾添加状态赋值:
public static void Start(int _maxPlayers, int _port) { // 原有逻辑不变 udpListener.BeginReceive(UDPReceiveCallback, null); isServerRunning = true; // 新增这行 Debug.Log($"Server started on port {Port}."); }
- 修改
UDPReceiveCallback()方法
在回调逻辑开头添加运行状态判断,同时异步接收前二次校验状态:
private static void UDPReceiveCallback(IAsyncResult _result) { try { if (!isServerRunning || udpListener == null) return; // 新增这行 IPEndPoint _clientEndPoint = new IPEndPoint(IPAddress.Any, 0); byte[] _data = udpListener.EndReceive(_result, ref _clientEndPoint); // 新增状态校验,避免处理过程中服务器停止仍发起新的异步接收 if (isServerRunning && udpListener != null) { udpListener.BeginReceive(UDPReceiveCallback, null); } // 后续原有逻辑不变 } // 原有catch逻辑不变 }
- 重写
Stop()方法
先修改运行状态再销毁监听实例,同时加空引用判断:
public static void Stop() { isServerRunning = false; if (tcpListener != null) { tcpListener.Stop(); tcpListener = null; } if (udpListener != null) { udpListener.Close(); udpListener = null; } clients.Clear(); if (packetHandlers != null) { packetHandlers.Clear(); } }
- 可选优化
TCPConnectCallback和SendUDPData方法也可以添加相同的isServerRunning和实例非空判断,避免TCP侧也出现同类已释放对象访问错误。
内容的提问来源于stack exchange,提问作者TheDoctorFromKDE
相关产品推荐
相关产品推荐

