• 异步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;
                    }
                }
            }
  • 相关阅读:
    GIL锁、进程池和线程池、同步和异步
    线程
    socket编程
    单例模式
    反射、自定义内置方法来定制类的功能、元类
    elasticSearch(一)--数据1
    docker学习整理(三)
    docker学习整理(二)
    docker学习整理(一)
    IDEA 配置mybatis生成代码
  • 原文地址:https://www.cnblogs.com/yeshuimaowei/p/8656821.html
Copyright © 2020-2023  润新知