我想知道是否有办法避免在我无法连接时获取SocketException而不是使用try / catch捕获SocketException。
我有这个代码检查服务器是否可用:
public bool CheckServerStatus(string IP, int Port)
{
try
{
IPAddress[] IPs = Dns.GetHostAddresses(IP);
using (Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp))
s.Connect(IPs[0], Port);
return true;
}
catch (SocketException)
{
return false;
}
}
提前致谢。
答案 0 :(得分:4)
您可以继承Socket
并提供具体实施:
public class MySocket : Socket{
//...
public boolean TryConnect(...){
}
}
你也可以代替一个布尔值,返回一个Result
对象来保存错误处理的异常:
public class Result {
public Exception Error { get; set; }
public boolean Success { get{ return Error != null; } }
}
答案 1 :(得分:3)
获得SocketException
不是问题;这是异常应该用于什么。根据您获得的异常类型,您可以采用不同的方式处理它们。如果你刚刚抓住Exception
而不是更具体的SocketException
,那就不好了。
你为什么要这么避免呢?正如评论所说,在某些地方,如果连接的另一端不可用,代码将会失败。只要确保你在适当的地方发现失败,就像你现在正在做的那样。
答案 2 :(得分:1)
也许你可以通过使用Ahmed approach来解决问题,但这只会让问题更深入。
没有这种测试方法的主要原因是竞争条件的可能性。想象一下,你会检查这样的套接字是否可行,然后你可以尝试在下一行中建立这个套接字,发生一个上下文切换(到另一个线程或应用程序),只为自己分配这个套接字。现在你仍然得到异常,你必须检查它(通过使用try-catch方法)。
因此,此测试只会为您的代码添加任何好处,因为您仍然必须为此方法的失败做好准备。这就是这个测试不存在的原因。
答案 3 :(得分:1)
我设法使用BeginConnect完成此操作,如下所示
int connectTimeoutMS = 1000;
IPEndPoint endPoint = GetEndPoint();
var evt = new AutoResetEvent(false);
_socket.BeginConnect(endPoint, (AsyncCallback)delegate { evt.Set(); }, null);
evt.WaitOne(connectTimeoutMS);