检查端口是否打开

时间:2012-08-06 23:55:44

标签: c# .net winforms

我似乎无法找到任何告诉我路由器中的端口是否打开的信息。 这甚至可能吗?

我现在的代码似乎并没有真正起作用......

private void ScanPort()
{
    string hostname = "localhost";
    int portno = 9081;
    IPAddress ipa = (IPAddress) Dns.GetHostAddresses(hostname)[0];
    try
    {
        System.Net.Sockets.Socket sock =
                new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
                                              System.Net.Sockets.SocketType.Stream,
                                              System.Net.Sockets.ProtocolType.Tcp);
        sock.Connect(ipa, portno);
        if (sock.Connected == true) // Port is in use and connection is successful
            MessageBox.Show("Port is Closed");
        sock.Close();
    }
    catch (System.Net.Sockets.SocketException ex)
    {
        if (ex.ErrorCode == 10061) // Port is unused and could not establish connection 
            MessageBox.Show("Port is Open!");
        else
            MessageBox.Show(ex.Message);
    }
}

10 个答案:

答案 0 :(得分:34)

试试这个:

using(TcpClient tcpClient = new TcpClient())
{
    try {
        tcpClient.Connect("127.0.0.1", 9081);
        Console.WriteLine("Port open");
    } catch (Exception) {
        Console.WriteLine("Port closed");
    }
}

您应该将127.0.0.1更改为192.168.0.1或路由器的IP地址。

答案 1 :(得分:19)

更好的解决方案,您甚至可以指定超时:

bool IsPortOpen(string host, int port, TimeSpan timeout)
{
    try
    {
        using(var client = new TcpClient())
        {
            var result = client.BeginConnect(host, port, null, null);
            var success = result.AsyncWaitHandle.WaitOne(timeout);
            if (!success)
            {
                return false;
            }

            client.EndConnect(result);
        }

    }
    catch
    {
        return false;
    }
    return true;
}

而且,在F#中:

let IsPortOpen (host: string, port: int, timeout: TimeSpan): bool =
    let canConnect =
        try
            use client = new TcpClient()
            let result = client.BeginConnect(host, port, null, null)
            let success = result.AsyncWaitHandle.WaitOne(timeout)
            match success with
            | false -> false
            | true ->
                   client.EndConnect(result)
                   true
        with
        | _ -> (); false
    canConnect

答案 2 :(得分:3)

如果您要连接到loopback adapter - localhost127.0.0.1there's no place like 127.0.0.1!),则不太可能会转到路由器。操作系统很聪明,可以识别出它是一个特殊的地址。如果您确实指定机器的“真实”IP地址,那么Dunno也是如此。

另请参阅此问题:What is the purpose of the Microsoft Loopback Adapter?

另请注意,在Windows中运行traceroute localhosttracert localhost)表明所涉及的唯一网络节点是您自己的计算机。路由器永远不会参与其中。

答案 3 :(得分:2)

无法知道端口是否在您的路由器中转发,除非该端口中有程序正在侦听。

正如您在克林顿的回答中所看到的,正在使用的.Net类是TcpClient,这是因为您正在使用TCP套接字进行连接。这就是操作系统建立连接的方式:使用套接字。但是,路由器只是将数据包(OSI模型的第3层)转发或转出。在你的情况下,你的路由器正在做什么叫做:NAT。它是由一个或多个私有IP共享的一个公共IP。这就是你进行端口转发的原因。

数据包路径中可能有很多路由器,你永远不会知道发生了什么。

假设您以传统方式发送信件。也许你可以在信中写下接收者必须回答你的信,以便检查他/她是否在那里(你和接收者是插座)。如果您收到答案,您将确定他/她在那里,但如果您没有收到任何东西,您不知道邮递员(在您的情况下是路由器)是否忘记发送信件,或接收器没有回答。你也永远不知道邮递员是否已经要求朋友发送那封信。此外,邮件员不会打开信件,以便知道他/她可能会回答,因为您正在等待回复。你所要做的就是等一段时间才能收到答案。如果你在那个时期没有收到任何东西,你会认为接收者不是你发的信。那是一个“超时”。

我看到了一个提到nmap软件的答案。这真的是一个非常好的和复杂的软,但我认为它将以相同的方式工作。如果该端口没有应用程序侦听,则无法知道它是否已打开。

如果我很清楚,请告诉我。

答案 4 :(得分:1)

路由器上的前向端口无法从局域网内部进行测试,您需要从WAN(Internet)端连接以查看端口转发是否正常工作。

多个互联网站点提供服务以检查端口是否已打开:

What's My IP Port Scanner

GRC | ShieldsUP!

如果要使用自己的代码进行检查,则需要确保通过外部代理重新路由TCP / IP连接或设置隧道。这与您的代码无关,它是基本的网络101。

答案 5 :(得分:1)

public static bool PortInUse(int  port)
{
    bool inUse = false;

    IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    IPEndPoint [] ipEndPoints = ipProperties.GetActiveTcpListeners();


    foreach(IPEndPoint endPoint in ipEndPoints)
    {
        if(endPoint.Port == port)
        {
            inUse = true;
            break;
        }
    }


    return  inUse;
}

答案 6 :(得分:0)

对我来说,在端口连接可用或经过一定的重试后,我需要阻塞。所以,我想出了这段代码:

public bool IsPortOpen(string host, int port, int timeout, int retry)
{
    var retryCount = 0;
    while (retryCount < retry)
    {
        if (retryCount > 0)
            Thread.Sleep(timeout);

        try
        {
            using (var client = new TcpClient())
            {
                var result = client.BeginConnect(host, port, null, null);
                var success = result.AsyncWaitHandle.WaitOne(timeout);
                if (success)
                    return true;

                client.EndConnect(result);
            }
        }
        catch
        {
            // ignored
        }
        finally { retryCount++; }
    }

    return false;
}

希望这有帮助!

答案 7 :(得分:0)

public string GetAvailablePort()
        {int startingPort=1000;
            string portnumberinformation = string.Empty;
            IPEndPoint[] endPoints;
            List<int> portArray = new List<int>();
            IPGlobalPr`enter code here`operties properties = IPGlobalProperties.GetIPGlobalProperties();`enter code here`


            //getting active tcp listners 
            endPoints = properties.GetActiveTcpListeners();
            portArray.AddRange(from n in endPoints
                               where n.Port >= startingPort
                               select n.Port);    

            portArray.Sort();

            for (int i = 0; i < portArray.Count; i++)
            {
                if (check condition)
                {
                    do somting
                }
            }

            return portnumberinformation;
        }

答案 8 :(得分:0)

除了BeginConnect之外,您还可以使用ConnectAsync(我认为是在.NET Framework 4.5中添加的)。

TcpClient client = null;

try {
    client = new TcpClient();
    var task = client.ConnectAsync(host, port);
    if (task.Wait(timeout)) {//if fails within timeout, task.Wait still returns true.
        if (client.Connected) {
            // port reachable
        }
        else
            // connection refused probably
    }
    else
        // timed out
}
catch (Exception ex) {
    // connection failed
}
finally {
    client.Close();
}

完整项目为here,因为paping拒绝运行,而且我找不到喜欢的其他“ ping host:port”工具。

答案 9 :(得分:-2)

如果它是路由器,则是通过

之类的在线服务进行检查的最简单方法

您还可以尝试使用 telenet 来检查端口是否可访问

telenet [ip-address] [port]