C#异步UDP侦听器SocketException

che*_*525 8 c# asynchronous udp socketexception

我有一个非常简单的异步UDP侦听器,设置为服务,它现在已经运行了一段时间,但它最近在SocketException上崩溃了An existing connection was forcibly closed by the remote host.我有三个问题:

  1. 是什么导致了这个?(我不认为UDP套接字有连接)
  2. 出于测试目的,我该如何复制它?
  3. 我怎样才能干净地处理异常,所以一切都会继续工作?

我的代码如下所示:

private Socket udpSock;
private byte[] buffer;
public void Starter(){
    //Setup the socket and message buffer
    udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
    buffer = new byte[1024];

    //Start listening for a new message.
    EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
    udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}

private void DoReceiveFrom(IAsyncResult iar){
    try{
        //Get the received message.
        Socket recvSock = (Socket)iar.AsyncState;
        EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
        int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
        byte[] localMsg = new byte[msgLen];
        Array.Copy(buffer, localMsg, msgLen);

        //Start listening for a new message.
        EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
        udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);

        //Handle the received message
        Console.WriteLine("Recieved {0} bytes from {1}:{2}",
                          msgLen,
                          ((IPEndPoint)clientEP).Address,
                          ((IPEndPoint)clientEP).Port);
        //Do other, more interesting, things with the received message.
    } catch (ObjectDisposedException){
        //expected termination exception on a closed socket.
        // ...I'm open to suggestions on a better way of doing this.
    }
}
Run Code Online (Sandbox Code Playgroud)

在recvSock.EndReceiveFrom()行抛出异常.

Kyl*_*ski 16

这个论坛帖子中,似乎UDP套接字也在接收ICMP消息并抛出异常时收到它们.也许这对于低级状态更新很有用,但我发现它很烦人.

首先,定义幻数

public const int SIO_UDP_CONNRESET = -1744830452;
Run Code Online (Sandbox Code Playgroud)

然后设置低级别io控件以忽略这些消息:

var client = new UdpClient(endpoint);
client.Client.IOControl(
    (IOControlCode)SIO_UDP_CONNRESET, 
    new byte[] { 0, 0, 0, 0 }, 
    null
);
Run Code Online (Sandbox Code Playgroud)