2012-01-26 9 views
6

Estoy tratando de escanear de manera asíncrona los puertos TCP. Como los puertos abiertos tardan solo unas pocas centésimas de milisegundos en completarse, están bien, pero cuando los puertos están cerrados, tengo que esperar la respuesta.¿Cómo hacer que el proceso de escaneo de puertos TCP sea más rápido?

Entonces, lo que ocurre es que ejecuto la aplicación y casi de inmediato veo que el puerto 80 está abierto. Entonces debo esperar como medio minuto para que todos los demás puertos sean escaneados.

EDITAR. Además, me gustaría mostrar la respuesta a medida que sucede, sin esperar a que se revisen otros puertos.

¿Cómo hacer esto más rápido?

private void btnStart_Click(object sender, EventArgs e) 
{ 
    for (int port = 79; port < 90; port++) 
    { 
     ScanPort(port); 
    } 
} 

private void ScanPort(int port) 
{ 
    TcpClient client = new TcpClient(); 
    client.BeginConnect(IPAddress.Parse("74.125.226.84"), port, new AsyncCallback(CallBack), client); 
} 

private void CallBack(IAsyncResult result) 
{ 
    bool connected = false; 

    using (TcpClient client = (TcpClient)result.AsyncState) 
    { 
     try 
     { 
      client.EndConnect(result); 
      connected = client.Connected; 
     } 
     catch (SocketException) 
     { 
     } 
    } 

    if (connected) 
    { 
     this.Invoke((MethodInvoker)delegate 
     { 
      txtDisplay.Text += "open2" + Environment.NewLine; 
     }); 
    } 
    else 
    { 
     this.Invoke((MethodInvoker)delegate 
     { 
      txtDisplay.Text += "closed2" + Environment.NewLine; 
     }); 
    } 
} 
+0

se abren casi simultáneamente, pero hasta que se agota el tiempo de espera, los puertos no activos se bloquean. por lo tanto, los puertos abiertos devuelven "open2" inmediatamente y los puertos cerrados esperan hasta que se alcance el timout – Matten

+0

@Matten, tampoco entiendo por qué los puertos cerrados se muestran casi al mismo tiempo. – NewHelpNeeder

+3

@NewHelpNeeder: No están "cerrados". En realidad, están protegidos por un firewall, por lo que no recibe el mensaje ICMP de "Puerto inalcanzable" que indicaría a su software que el puerto está cerrado. Entonces, la única indicación que recibe es un tiempo de espera sin respuesta. Como el tiempo de espera es el mismo para todas las conexiones, y usted inició todas las conexiones a la vez, los tiempos de espera también se producen al mismo tiempo. –

Respuesta

7

Puede usar WaitHandle BeginConnect Returns para esperar solo tanto tiempo.

using (var tcp = new TcpClient()) 
{ 
    var ar = tcp.BeginConnect(host, port, null, null); 
    using (ar.AsyncWaitHandle) 
    { 
     //Wait 2 seconds for connection. 
     if (ar.AsyncWaitHandle.WaitOne(2000, false)) 
     { 
      try 
      { 
       tcp.EndConnect(ar); 
       //Connect was successful. 
      } 
      catch 
      { 
       //EndConnect threw an exception. 
       //Most likely means the server refused the connection. 
      } 
     } 
     else 
     { 
      //Connection timed out. 
     } 
    } 
} 
+0

Funciona para mí +1 – Muthukkumaran

+0

También funciona para mí :-) – jreichert

Cuestiones relacionadas