Search code examples
c#asynchronousport-scanning

How to make the process of scanning TCP ports faster?


I'm trying to asynchronously scan TCP ports. Since the open ports take just a few hundredths of milliseconds to complete they're fine, but when ports are closed I have to wait for the response.

So what happens is that I run the app and almost right away I see the port 80 to be open. Then I must wait like half a minute for all the other ports to get scanned.

EDIT. plus I would like to show the respond as it happens, with out waiting for other ports to be checked.

How to make this faster?

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

Solution

  • You can use the WaitHandle BeginConnect returns to only wait so long.

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