2

我想知道是否有办法避免在我无法连接时获得 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;
        }
    }

提前致谢。

4

4 回答 4

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; } }
}
于 2013-05-02T09:30:42.457 回答
3

得到一个SocketException不是问题;这就是应该使用异常的目的。根据您获得的异常类型,您可以以不同的方式处理它们。如果你只是抓住Exception而不是更具体的,那就太糟糕了SocketException

为什么你这么想避免它?正如评论所说,在某个时候,某个地方,如果连接的另一端不可用,代码将失败。只要确保你在适当的地方发现失败,就像你现在正在做的那样。

于 2013-05-02T09:32:13.597 回答
2

I managed to accomplish this using BeginConnect as follows

int connectTimeoutMS = 1000;
IPEndPoint endPoint = GetEndPoint();
var evt = new AutoResetEvent(false);
_socket.BeginConnect(endPoint, (AsyncCallback)delegate { evt.Set(); }, null);
evt.WaitOne(connectTimeoutMS);
于 2013-10-25T15:50:20.593 回答
1

也许您可以通过使用Ahmed 方法首先解决问题,但这只是将问题移得更深。

没有这种测试方法的主要原因是可能存在竞争条件。想象一下,您会检查这样的套接字是否可能,并且在您尝试在下一行中建立此套接字之前,会发生上下文切换(到另一个线程或应用程序),它只是为自己分配此套接字。现在你仍然得到异常并且你必须检查它(通过使用 try-catch 方法)。

所以这个测试对你的代码没有任何好处,因为你仍然需要为这个方法的失败做好准备。这就是这个测试不存在的原因。

于 2013-05-02T09:41:32.213 回答