如何找出哪个端点导致了 SocketException,UdpClient

Posted

技术标签:

【中文标题】如何找出哪个端点导致了 SocketException,UdpClient【英文标题】:How to find out which endpoint caused the SocketException, UdpClient 【发布时间】:2011-09-20 23:10:14 【问题描述】:

我在服务器端使用 UdpClient,它正在向客户端(多个客户端)发送数据。 突然,客户端停止侦听 udp 端口​​,服务器在调用 endRecieve 或 beginRecieve 时遇到 SocketException。

据我了解,这是因为“ICMP 目标无法访问”,它只是告诉服务器端口已关闭。没关系,但是 SocketExceptions 都没有告诉我它来自哪个端点。

我如何知道哪个端点已关闭,以便服务器停止向其发送并导致更多 SocketExceptions?

或者有没有办法让 Udpclient 停止抛出这些 SocketExceptions,这样如果客户端在某某秒后没有响应,我可以让客户端超时。

【问题讨论】:

【参考方案1】:

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

我的套接字周围有一个通信包装类(我们称之为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]\d3|[1-5]\d4|[1-9]\d0,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.");
    

【讨论】:

以上是关于如何找出哪个端点导致了 SocketException,UdpClient的主要内容,如果未能解决你的问题,请参考以下文章

如何找出 Oracle 死锁的原因

如何找出点击了哪个 DataGridView?

如何找出在哪个提交中添加了特定代码?

如何找出点击了哪个按钮?

如何找出Linux系统高IO的思路总结

如何找出哪个课程占用的内存最多?