2012-08-06 17 views
14

Parece que no encuentro nada que me diga si un puerto en mi enrutador está abierto o no. ¿Esto es posible?Compruebe si un puerto está abierto

El código que tiene en este momento no parece realmente a trabajar ...

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

¿Cómo falla? ¿Los resultados no son los esperados, recibe una excepción? – TheEvilPenguin

+0

también si su código se conecta al puerto debería decir que el puerto está abierto no cerrado –

+0

@TheEvilPenguin Quiero que diga que mi puerto está abierto porque lo reenvío en mi enrutador, pero no se puede conectar ... –

Respuesta

23

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 a algo así como 127.0.0.1 192.168.0.1 o cualquiera que sea la dirección IP de su enrutador.

+0

Todavía no lo hace No funciona si utilizo 192.168.1.1 –

+0

¿qué ocurre cuando intentas usar el código? –

+0

Dice que no se puede conectar, incluso si el puerto está abierto. –

2

Si se conecta a la loopback adapterlocalhost o 127.0.0.1 (there's no place like 127.0.0.1!), es poco probable que alguna vez vaya a cabo con el router. 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 especificas la dirección IP "real" de tu máquina.

Ver también esta pregunta: What is the purpose of the Microsoft Loopback Adapter?

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

1

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

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

What's My IP Port Scanner

GRC | ShieldsUP!

Si desea consultar con su propio código, entonces usted necesita para asegurarse de que el TCP/La conexión IP se redirecciona a través de un proxy externo o configura un túnel. Esto no tiene nada que ver con su código, que es una red básica 101.

12

Una mejor solución en la que incluso se puede 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 Fa #:

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 
+0

¿Qué tan eficiente es este método? Especialmente en F #? Estoy trabajando en una tesis para un protocolo de red y parte del (pre) proceso es componer una lista de puertos disponibles. – czifro

+0

debe ser tan eficiente como el C# uno ... pero mídelo usted mismo por si acaso? – ympostor

+0

podría este mismo patrón ser utilizado para System.Net.Sockets.UdpClient? – tatmanblue

2

Hay no hay manera de saber si el puerto se reenvía en su enrutador, excepto si hay un programa escuchando en ese puerto.

Como puede ver en la respuesta de Clinton, la clase .Net que se utiliza 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: usando un socket. Sin embargo, un enrutador simplemente reenvía los paquetes (capa 3 del Modelo OSI) dentro o fuera. En su caso, lo que enruta está haciendo lo que se llama: NAT. Es una IP pública compartida por una o más IP privadas. Es por eso que estás haciendo un reenvío de puertos.

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

Imaginemos que está enviando una carta de la manera tradicional. Tal vez pueda escribir en la carta que el receptor debe responderle para verificar que esté allí (usted y el receptor son los enchufes).Si recibe una respuesta, estará seguro de que está allí, pero si no recibe nada, no sabe si el cartero (en su caso, el enrutador) se olvidó de entregar la carta, o si el receptor no lo hizo. contestada. 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 recibes nada en ese período, supondrás que el receptor no se envió la carta. Eso es un "tiempo de espera".

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

Háganme saber si no tengo dudas.

Cuestiones relacionadas