C# Async UDP listener SocketException

12,360

Solution 1

From this forum thread, it seems that the UDP socket is also receiving ICMP messages and throwing exceptions when they are received. Maybe this is great for low level status updates, but I found it annoying.

First, define the magic number

public const int SIO_UDP_CONNRESET = -1744830452;

Then set the low level io control to ignore these messages:

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

Solution 2

I've seen that error with UDP if a packet is somehow truncated or otherwise not completely delivered. At least, I think that's what happens. I've never been able to duplicate it reliably.

I would suggest that you catch the SocketException, log it (if you want), and then dispose of that socket. Then call Starter again:

catch (SocketException)
{
    // log error
    udpSock.Close();
    Starter();
}
Share:
12,360

Related videos on Youtube

chezy525
Author by

chezy525

Updated on June 04, 2022

Comments

  • chezy525
    chezy525 about 1 year

    I have a pretty simple Asynchronous UDP listener, setup as a service, and it's been working quite well for awhile now, but it recently crashed on a SocketException An existing connection was forcibly closed by the remote host. I have three questions:

    1. What's causing this? (I didn't think UDP sockets had a connection)
    2. How can I duplicate it, for testing purposes?
    3. How can I cleanly handle the exception, so everything will continue to work?

    My code looks something like the following:

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

    The exception is being thrown at the recvSock.EndReceiveFrom() line.

  • chezy525
    chezy525 over 12 years
    This is what I ended up doing, but I'd still like to know what's actually causing this exception (i.e. prove what you think is correct).
  • Kongress
    Kongress about 12 years
    @chezy525 I believe these socket exceptions usually arise from ICMP "Destination/Port/etc. unreachable" messages on your socket. How you'd get one if you're just listening, I'm not sure. Just a thought.
  • taher chhabrawala
    taher chhabrawala over 11 years
    try enabling system.net tracing and see whats going underneath
  • Kevan
    Kevan over 10 years
    Great Man! Hi had same problem of receiving ICMP messages and throwing exceptions when they are received. Which is solved by your coding trick!
  • chezy525
    chezy525 almost 10 years
    @Kyle, I finally got around to fully testing this! It would seem this was the actual root cause of the exception. For reference, I ended up using both your answer and Jim's, so that even if there is an exception, the listener gets restarted.
  • Nate Zaugg
    Nate Zaugg over 9 years
    Broken Link. This answer should be changed to either update the link or include the information that the link pointed to.

Related