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