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

原文地址:https://www.cnblogs.com/yeshuimaowei/p/8656821.html

时间: 2024-08-02 13:40:02

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

Windows10 下 github ssh 访问出现 Permission denied(publickey)错误的解决方法

Windows10 下 github ssh 访问出现 Permission denied(publickey)错误的解决方法. 错误信息: git clone [email protected]:ediwang/envsetup.git Cloning into 'envsetup'... [email protected]: Permission denied (publickey). fatal: Could not read from remote repository. Please

.net 访问远程的MSSQL报System.AccessViolationException错误的解决方法

访问远程的数据库时 报错,本地数据库正常 netsh winsock reset   --运行此命令,解决. netsh winsock reset命令,作用是重置 Winsock 目录.如果一台机器上的Winsock协议配置有问题的话将会导致网络连接等问题,就需要用netsh winsock reset命令来重置Winsock目录借以恢复网络.这个命令可以重新初始化网络环境,以解决由于软件冲突.病毒原因造成的参数错误问题. netsh是一个能够通过命令行操作几乎所有网络相关设置的接口,比如设置

C# Socket基础(一)之启动异步服务监听

本文主要是以代码为主..NET技术交流群 199281001 .欢迎加入. //通知一个或多个正在等待的线程已发生事件. ManualResetEvent manager = new ManualResetEvent(false); 1 //负责监听的套接字 private Socket socketServer; 2 /// <summary> 3 /// 启动服务 4 /// </summary> 5 private void CreateSocketService() 6 {

关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误

关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误原因:listener.ora中没有指定监听服务器名. 如下是解决思路: 尝试1.通过重启服务的方式启动数据库,再次连接仍无法连接服务器. 尝试2.既然第一种方法不能解决问题,那就第二种方法.考虑监听listener.ora 步骤如下: 在oracle服务器Oracle安装目录(我的在C:\oracle\product\10.2.0\db_1\NETWORK\ADMIN下,每个人的不一样,根据自己的情况

Xamarin.Forms 监听Button的按下、释放事件

Xamarin.Forms 监听Button的按下.释放事件 工作中遇到这样的一个需求,模仿微信发生语音功能,需要实现按钮按下开始录音,按钮释放录音结束, Xamarin.Forms中Button没有这样的事件,那么我们如何实现对Button按下,释放两个事件的监听呢? 当然这里我们再次用到了CustomRenderer,一旦遇到Xamrin.Forms无法实现的某些功能,我们就可以 通过CustomRenderer来处理. 首先:我们自定义一个VoiceRecordButton继承于Butto

(转)C#在父窗口中调用子窗口的过程(无法访问已释放的对象)

C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象 笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中,加入了如下代码来创建和显示子窗口: Private childFrm myChildFrm = null; //定义子窗口对象 private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e) { myChildF

C# WinForm:无法访问已释放的对象

C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象 笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中,加入了如下代码来创建和显示子窗口: Private childFrm myChildFrm = null; //定义子窗口对象private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e){        myC

C# Socket连接 无法访问已释放的对象

在进行Socket长连接时,若服务器或客户端出现异常时,另外一端对Socket对话进行操作时,程序会出现无法访问已释放的对象的问题.例如客户端出现问题主动断开Socket时,当服务器操作Socket时,比如主动断开Socket会话,那么程序会出现“无法方位已释放的对象”,是由于客户端的原因导致服务器和客户端的Socket已经不存在或连接已经断开,即Socket已经释放,服务器再操作服务器和客户端的Socket肯定会报错,因此在服务器或客户端一侧操作Socket时,必须首先判断Socket是否存在

WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭

原文:WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭 在我们开发WCF项目的时候,常常会碰到一些莫名其妙的错误,有时候如果根据它的错误提示信息,一般很难定位到具体的问题所在,而由于WCF服务的特殊性,调试起来也不是那么方便,因此往往会花费不少时间来进行跟踪处理.本文介绍我在我在我的框架里面使用WCF服务的时候,出现的一个常见错误的处理方法,它的提示信息是:基础连接已经关闭: 连接被意外关闭.这种情况我碰到的有两种,一种是返回DataTable的时候出现的,一种是返回实体类