这是一种可行的方法来确定服务器是否可以为Http或Ws使用端口?

时间:2016-05-20 19:34:38

标签: c# sockets http websocket

我正在开发一个托管浏览器控件的应用程序。客户端(在浏览器中,使用本地主机地址)通过websockets与服务器通信,服务器处理Http请求。

用户可以为Http和Ws定义端口,但是(因为可以打开应用程序的几个实例)我需要检测,如果它们可用 - 如果没有,我通知用户将使用备用端口

使用HttpListener验证是否阻止了预期的Http端口,但是(由于我不明白的原因),侦听器显然可以使用另一个应用程序已经使用的端口进行websocket连接。

所以我最终得到了以下代码,似乎可以完成这项工作。我用它来首先测试一个指定的端口,如果失败了,我会遍历一系列端口号并尝试直到该方法返回True

private static bool testPort(int port)
{
    bool result = false;

    System.Net.IPEndPoint endpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, port);

    using (System.Net.Sockets.Socket s = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)) {
        try {
            Console.WriteLine("Testing port {0}", port);

            s.Connect(endpoint);
            s.Bind(endpoint);

            result = true;
        } catch (SocketException ex) {
            switch (ex.SocketErrorCode) {
                case SocketError.InvalidArgument:
                    //This error is apparently thrown when a port is occupied.
                    result = false;

                    break;
                case SocketError.ConnectionRefused:
                    //NOTE: This error is apparently thrown when a port is not occupied (but the connection fails, because the socket cannot connect since the port is not being used?).
                    result = true;
                    break;

                default:
                    result = false;
                    break;
            }
        } catch (Exception ex) {
            result = false;
        }
    }

    return result;
}

但我不确定,如果它可能只是一个“幸运的巧合”。就像我提到的那样,它可以测试它,但它有意义吗?而且:它可靠吗?

1 个答案:

答案 0 :(得分:0)

代码受竞争条件限制。连接调用可能会失败,因为端口未被使用,但是另一个程序可能会在函数返回之前获取该端口。

测试一堆端口也可能导致明显的延迟。例如,防火墙可以配置为丢弃数据包而不是发送连接拒绝响应。在这种情况下,连接调用将阻塞,直到达到超时。

作为旁注,Bind需要在Connect工作之前调用,但在这种情况下,应删除Bind调用。您无法将连接套接字绑定到您尝试连接的同一端点。