我自己也在处理同样的问题,所以我很想看看是否有人能提出更好的解决方案,但目前我有几个想法:
我有一个通信包装类(我们称之为AsyncComm
),它围绕着我的套接字,并在构造时从其所有者类传递异常处理程序委托。异常处理程序委托带有异常和抛出它的AsyncComm
实例的引用参数。然后我放置了
try
{
{
catch (Exception e)
{
CallExceptionHandlerDelegate(e, this);
}
在我的
AsyncComm
中的每个异步处理程序方法中,它们可以将其异常抛出到链上。在我的情况下,异常处理程序使用对
AsyncComm
实例的引用来调用
AsyncComm
实例中的方法,以告诉它重新初始化其套接字。您可以更改该行为以满足您需要停止不断获取
SocketExceptions
的要求。
关于确定异常来自哪个端点,我目前唯一的想法是从
SocketException.Message
字符串的末尾解析端点,但这似乎相当笨拙。
更新:这是一个笨拙的方法,但它有效。解析代码如下,其中一些代码取自
this question。
private IPEndPoint parseEndPointFromString(string input)
{
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.");
}
}