C#异步UDP侦听器SocketException

时间:2011-03-04 20:40:29

标签: c# asynchronous udp socketexception

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

  1. 造成这种情况的原因是什么? (我不认为UDP套接字有连接)
  2. 为了测试目的,我如何复制它?
  3. 如何干净地处理异常,以便一切都能继续工作?
  4. 我的代码如下所示:

    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.
        }
    }
    

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

2 个答案:

答案 0 :(得分:15)

this forum thread开始,UDP套接字似乎也在接收ICMP消息并抛出异常。也许这对于低级状态更新很有用,但我发现它很烦人。

首先,定义幻数

public const int SIO_UDP_CONNRESET = -1744830452;

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

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

答案 1 :(得分:2)

如果数据包以某种方式被截断或未完全传递,我已经看到了UDP的错误。至少,我这就是发生的事情。我从来没有能够可靠地复制它。

我建议您抓住SocketException,记录它(如果需要),然后处置该套接字。然后再次致电Starter

catch (SocketException)
{
    // log error
    udpSock.Close();
    Starter();
}