异步Udp监听关闭 出现异常,访问已释放的资源或者其他错误的解决方法

Posted yeshuimaowei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步Udp监听关闭 出现异常,访问已释放的资源或者其他错误的解决方法相关的知识,希望对你有一定的参考价值。

在开发异步Udp程序的过程中,通常在关闭UDP的时候回遇到诸如socket 访问已释放的资源之类的异常,如下简单操作下:

 

1 Udp的监听
2 this.serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
3                 this.serverSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress,true);
4                 this.serverSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.12"), port));
5                 EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
6                 this.serverSocket.BeginReceiveFrom(this.buff, 0, this.buff.Length, SocketFlags.None, ref remoteEP, new AsyncCallback(this.Receive), remoteEP);
Udp的关闭
if (this.serverSocket != null)
  {
                    this.serverSocket.Close();
                    this.serverSocket = null;
  }


当在进行关闭的时候,可能就出现错误,这个应该是多线程资源同步到问题,主线程进行了关闭,然而Udp线程也同样在访问socket,socket都释放了,而Udp线程却还在进行,因此产生异常;

解决的方法很简单,在Udp中访问serverSokcet加一个线程锁,再关闭的时候就应该不会产生异常了!


如下:


private void Receive(IAsyncResult ar)
        {
            IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);
            EndPoint endPoint = point;
            try
            {
                lock (locker)
                {
                    if (serverSocket != null)
                    {
                        int num = this.serverSocket.EndReceiveFrom(ar, ref endPoint);
                        List<byte> recBytes = new List<byte>();
                        for (int i = 0; i < num; i++)
                        {
                            recBytes.Add(this.buff[i]);
                        }
                        this.OnDataReceived(new DataReceivedEventArgs(endPoint, recBytes));
                    }
                }
            }
            catch
            {
            }
            finally
            {
                lock (locker)
                {
                    if(serverSocket!=null)
                    this.serverSocket.BeginReceiveFrom(this.buff, 0, this.buff.Length, SocketFlags.None, ref endPoint, new AsyncCallback(this.Receive), endPoint);
                }
            }

        }
public void Close()
        {           
            lock (locker)
            {
                if (this.serverSocket != null)
                {
                    this.serverSocket.Close();
                    this.serverSocket = null;
                }
            }
        }

 

以上是关于异步Udp监听关闭 出现异常,访问已释放的资源或者其他错误的解决方法的主要内容,如果未能解决你的问题,请参考以下文章

无法访问已释放的对象,该怎么解决

select+异步

Android 基于UDP的Socket通信

RAII

with异常

UDP的阻塞式监听不触发问题