How to find out which endpoint raised a SocketException, UdpClient

I use UdpClient on the server and it sends data to the client end (more than one client). Suddenly, the client stops listening to the udp port, and the server receives a hit with a SocketException, either when calling endRecieve or beginRecieve.

As far as I understand, this is due to the fact that "ICMP Destination Unreachable" just tells the server that the port is closed. This is normal, but not one of the SocketExceptions tells me which endpoint it is from.

How can I find out which endpoint is closed, so the server stops sending it and causes more SocketExceptions?

Or is there a way that Udpclient will stop throwing these SocketExceptions so that I can time out clients if they don't respond after seconds.

+4
source share
1 answer

I am dealing with the same problem, so I will be interested to know if anyone is coming up with a better solution, but so far I have a couple of ideas:

I have a class of comm AsyncComm (let it be called AsyncComm ) around my sockets to which the delegate of the exception handler from its owner class is passed when creating it. The exception handler delegate accepts the exception arguments and a reference to the AsyncComm instance that threw it. Then i put

 try { // Do stuff here { catch (Exception e) { CallExceptionHandlerDelegate(e, this); } 

in each of my async handler methods in AsyncComm so that they can AsyncComm their exceptions in the chain. In my case, the exception handler uses the AsyncComm instance AsyncComm to call the method on the AsyncComm instance to tell it to reinitialize its socket. You can change this behavior to whatever you need to constantly receive SocketExceptions .

Regarding the definition of the endpoint from which the exception came, the only idea I have in mind right now is to parse the endpoint from the end of the SocketException.Message line, but it looks like kludge.

Update . This is kludge, but it works. Below is the analysis code, some of which are taken from this question .

 private IPEndPoint parseEndPointFromString(string input) { // Matches 1-255.1-255.1-255.1-255:0-65535. I think. const string IPPortRegex = @"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)"; Match match = Regex.Match(input, IPPortRegex); if (match.Success) { string IPPortString = match.Value; string[] ep = IPPortString.Split(':'); if (ep.Length != 2) throw new FormatException("Invalid endpoint format"); IPAddress ip; if (!IPAddress.TryParse(ep[0], out ip)) { throw new FormatException("Invalid IP address"); } int port; if (!int.TryParse(ep[1], out port)) { throw new FormatException("Invalid port"); } return new IPEndPoint(ip, port); } else { throw new FormatException("Invalid input string, regex could not find an IP:Port string."); } } 
0
source

All Articles