Проверьте, открыт ли порт

Я не могу найти ничего, что говорит мне, открыт ли порт в моем маршрутизаторе или нет. Возможно ли это?

Код, который у меня есть сейчас, действительно не работает...

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);
    }
}

Ответы

Ответ 1

Попробуйте следующее:

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-адрес вашего маршрутизатора.

Ответ 2

Лучшее решение, в котором вы даже можете указать тайм-аут:

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

Ответ 3

Если вы подключаетесь к loopback adapterlocalhost или 127.0.0.1 (там не место, как 127.0.0.1!), вы вряд ли когда-нибудь выйдете на маршрутизатор. ОС достаточно умна, чтобы признать, что это специальный адрес. Dunno, если это верно, если вы действительно указываете свой "настоящий" IP-адрес вашего компьютера.

Смотрите также этот вопрос: Какова цель адаптера Loopback Microsoft?

Также обратите внимание, что запуск traceroute localhost (tracert localhost в Windows) показывает, что единственная сеть node связана с вашей собственной машиной. Маршрутизатор никогда не участвует.

Ответ 4

Нет никакого способа узнать, переадресован ли порт на вашем маршрутизаторе, кроме случаев, когда на этом порту прослушивается программа.

Как вы можете видеть в ответе Клинтона, используемый класс .Net является TcpClient, и это потому, что вы используете TCP-сокет для подключения. Именно так операционные системы устанавливают соединения: используя сокет. Однако маршрутизатор просто пересылает пакеты (уровень 3 модели OSI) внутрь или наружу. В вашем случае то, что делает ваш маршрутизатор, называется: NAT. Это один общедоступный IP-адрес, общий для одного или нескольких частных IP-адресов. Вот почему вы делаете переадресацию портов.

На пути пакетов может быть много маршрутизаторов, и вы никогда не узнаете, что произошло.

Представим, что вы отправляете письмо традиционным способом. Возможно, вы можете написать в письме, на которое должен ответить получатель, чтобы убедиться, что он/она там (вы и получатель - сокеты). Если вы получите ответ, вы будете уверены, что он/она там, но если вы ничего не получите, вы не будете знать, забыл ли почтальон (в вашем случае маршрутизатор) доставить письмо или получатель не получил ответил. Вы также никогда не узнаете, попросил ли почтальон друга доставить это письмо. Более того, почтальон не откроет письмо, чтобы знать, что он/она может ответить, потому что вы ждете ответа. Все, что вы можете сделать, это подождать некоторое время, чтобы получить ответ. Если вы ничего не получите в этот период, вы будете считать, что получатель находится не там, куда вы отправили письмо. Это "тайм-аут".

Я видел ответ, упоминающий программное обеспечение Nmap. Это действительно очень хорошая и сложная программа, но я думаю, что она будет работать точно так же. Если в этом порту нет приложения, которое прослушивает, нет способа узнать, открыто оно или нет.

Пожалуйста, дайте мне знать, если я был ясен.

Ответ 5

Перенос порта на маршрутизаторе не может быть протестирован из локальной сети, вам необходимо подключиться со стороны WAN (интернет), чтобы узнать, работает ли работа с портами.

Несколько интернет-сайтов предлагают услуги, чтобы проверить, открыт ли порт:

Что сканирует мой IP-порт

GRC | ShieldsUP!

Если вы хотите проверить свой собственный код, вам нужно убедиться, что соединение TCP/IP перенаправляется через внешний прокси-сервер или настраивает туннель. Это не имеет никакого отношения к вашему коду, это базовая сеть 101.

Ответ 6

Мне нужно было что-то блокировать, пока соединение с портом не станет доступным или после определенного количества попыток. Итак, я понял этот код:

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

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;
}

Ответ 8

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;
        }