如何找出导致SocketException发生的端点,UdpClient

4
我在服务器端使用了一个UdpClient,并向客户端 (多个客户端) 发送数据。突然间,客户端停止监听udp端口,服务器端遇到SocketException,无论是在调用endRecieve还是beginRecieve时。
据我所知,这是因为出现了“ICMP目标不可达”,它只是告诉服务器端该端口已关闭。这没关系,但是这两种SocketExceptions都没有告诉我来自哪个终端点。
如何知道哪个终端点已关闭,以便服务器端停止向其发送数据并避免更多的SocketExceptions呢?
或者,是否有一种方法可以使Udpclient停止抛出这些SocketExceptions,以便我可以让客户端在几秒钟内不响应时超时?
1个回答

0

我自己也在处理同样的问题,所以我很想看看是否有人能提出更好的解决方案,但目前我有几个想法:

我有一个通信包装类(我们称之为AsyncComm),它围绕着我的套接字,并在构造时从其所有者类传递异常处理程序委托。异常处理程序委托带有异常和抛出它的AsyncComm实例的引用参数。然后我放置了

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

在我的AsyncComm中的每个异步处理程序方法中,它们可以将其异常抛出到链上。在我的情况下,异常处理程序使用对AsyncComm实例的引用来调用AsyncComm实例中的方法,以告诉它重新初始化其套接字。您可以更改该行为以满足您需要停止不断获取SocketExceptions的要求。
关于确定异常来自哪个端点,我目前唯一的想法是从SocketException.Message字符串的末尾解析端点,但这似乎相当笨拙。 更新:这是一个笨拙的方法,但它有效。解析代码如下,其中一些代码取自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.");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接