Compruebe si un puerto está abierto

Parece que no puedo encontrar nada que me diga si un puerto en mi enrutador está abierto o no. ¿Es esto posible?

El código que tengo en este momento realmente no parece funcionar …

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

Prueba esto:

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

Probablemente debería cambiar 127.0.0.1 a algo así como 192.168.0.1 o cualquiera que sea la dirección IP de su enrutador.

Una mejor solución donde incluso puedes especificar un tiempo de espera:

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

Y, en 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 

Si se está conectando al adaptador de bucle de retorno ( localhost o 127.0.0.1 (¡ no hay lugar como 127.0.0.1! ), Es poco probable que salga al enrutador). El sistema operativo es lo suficientemente inteligente como para reconocer que es una dirección especial. No sé si eso también es cierto si realmente especifica la dirección IP “real” de su máquina.

Vea también esta pregunta: ¿Cuál es el propósito del Microsoft Loopback Adapter?

También tenga en cuenta que ejecutar traceroute localhost ( tracert localhost en Windows) muestra que el único nodo de red involucrado es su propia máquina. El enrutador nunca está involucrado.

No hay forma de saber si el puerto se reenvía en su enrutador, excepto si hay un progtwig escuchando en ese puerto.

Como puede ver en la respuesta de Clinton, la clase .Net que se está utilizando es TcpClient y eso se debe a que está utilizando un socket TCP para conectarse. Esa es la forma en que los sistemas operativos hacen conexiones: utilizando sockets. Sin embargo, un enrutador simplemente reenvía los paquetes (capa 3 del modelo OSI) hacia adentro o hacia afuera. En su caso, lo que hace su enrutador es lo que se llama: NAT. Es una IP pública compartida por una o más IP privadas. Por eso estás haciendo un reenvío de puertos.

Puede haber muchos enrutadores en la ruta de los paquetes y nunca sabrá lo que sucedió.

Imaginemos que estás enviando una carta de la manera tradicional. Quizás pueda escribir en la carta que el receptor debe responderle para que pueda verificar que él / ella está allí (usted y el receptor son los sockets). Si recibe una respuesta, se asegurará de que él / ella esté allí, pero si no recibe nada, no sabe si el cartero (en su caso, el enrutador) olvidó entregar la carta, o si el destinatario no la recibió. contestado. Tampoco sabría nunca si el cartero le ha pedido a un amigo que le entregue esa carta. Además, el cartero no abrirá la carta para saber que puede responder porque está esperando una respuesta. Todo lo que puede hacer es esperar un tiempo para recibir la respuesta. Si no recibe nada en ese período, asumirá que el destinatario no fue a donde envió la carta. Eso es un “tiempo de espera”.

Vi una respuesta mencionando el software nmap. Es realmente un software muy bueno y complejo, pero creo que funcionará de la misma manera. Si no hay una aplicación escuchando en ese puerto, no hay manera de saber si está abierta o no.

Por favor, hazme saber si estaba claro.

Un puerto de reenvío en el enrutador no se puede probar desde dentro de la LAN, debe conectarse desde el lado de la WAN (internet) para ver si un puerto de reenvío funciona o no.

Varios sitios de Internet ofrecen servicios para verificar si un puerto está abierto:

¿Cuál es mi escáner de puerto IP?

GRC | ShieldsUP!

Si desea verificar con su propio código, debe asegurarse de que la conexión TCP / IP se redireccione a través de un proxy externo o configure un túnel. Esto no tiene nada que ver con su código, es la red básica 101.

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

Para mí, necesitaba algo de locking hasta que la conexión al puerto esté disponible o después de una cierta cantidad de rebashs. Entonces, me di cuenta de este código:

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

¡Espero que esto ayude!