C# - 避免得到SocketException

时间:2013-05-02 09:26:09

标签: c# sockets exception disconnect

我想知道是否有办法避免在我无法连接时获取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 个答案:

答案 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);