避免得到SocketException
本文关键字:SocketException | 更新日期: 2023-09-27 18:11:52
我想知道是否有一种方法可以避免在我无法连接时获得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;
}
}
您可以子类化Socket
并提供您的具体实现:
public class MySocket : Socket{
//...
public boolean TryConnect(...){
}
}
您也可以代替布尔值,返回一个Result
对象,该对象保存异常以供错误处理:
public class Result {
public Exception Error { get; set; }
public boolean Success { get{ return Error != null; } }
}
获得SocketException
不是问题;这就是应该使用异常的原因。根据得到的异常类型,可以用不同的方式处理它们。如果您只捕获Exception
而不捕获更具体的SocketException
,那将是糟糕的。
你为什么这么想避开它?正如注释所说,在某个时刻,某个地方,如果连接的另一端不可用,代码将失败。只要确保你在适当的地方发现了失败,就像你现在所做的那样。
我使用BeginConnect实现了这一点,如下所示
int connectTimeoutMS = 1000;
IPEndPoint endPoint = GetEndPoint();
var evt = new AutoResetEvent(false);
_socket.BeginConnect(endPoint, (AsyncCallback)delegate { evt.Set(); }, null);
evt.WaitOne(connectTimeoutMS);
也许您可以使用Ahmed方法首先解决问题,但这只是将问题推向更深层次。
不存在这种测试方法的主要原因是存在竞争条件的可能性。想象一下,您将检查这样的套接字是否可能,并且在您尝试在下一行建立这个套接字之前,会发生上下文切换(到另一个线程或应用程序),该线程或应用程序只是为自己分配这个套接字。现在您仍然会得到异常,并且必须检查它(通过使用try-catch方法)。
所以这个测试对你的代码没有任何好处,因为你仍然需要为这个方法的失败做好准备。这就是这个测试不存在的原因