如何加速扫描TCP端口的过程?

6

我正在尝试异步扫描TCP端口。由于打开的端口只需要几百分之一秒就能完成,所以它们很好处理,但当端口关闭时我必须等待响应。

因此,在运行应用程序后,我几乎立即看到端口80打开。然后我必须等待大约半分钟才能扫描完所有其他端口。

编辑。此外,我希望可以实时显示响应,而无需等待检查其他端口。

如何使这个过程更快?

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

它们几乎同时打开,但在超时到达之前,未激活的端口会被阻塞。因此,打开的端口立即返回“open2”,而关闭的端口则等待超时到达。 - Matten
@Matten,我也不明白为什么关闭的端口几乎同时显示。 - NewHelpNeeder
3
他们并非“被关闭”。实际上,它们被防火墙隐身处理,这样你的软件就收不到 ICMP 的“端口不可达”信息,告诉你该端口已关闭。所以你唯一能得到的指示是超时而没有响应。由于所有连接的超时时间相同,并且你同时启动了所有连接,因此所有的超时也会同时发生。 - Ben Voigt
@Ben Voigt,这是好消息。 - NewHelpNeeder
2
如果您正在针对Windows机器进行测试,则应注意,如果您的扫描触发SYN洪水保护,连接行为将会改变。请参阅:http://msdn.microsoft.com/en-us/library/ff648853.aspx和http://technet.microsoft.com/en-us/library/cc759239%28WS.10%29.aspx。 - meklarian
@meklarian,我并没有考虑任何特定的目标,我只是想检查任何给定IP地址上的端口,但这是关于Win TCP堆栈加固的好信息。 - NewHelpNeeder
1个回答

8
你可以使用WaitHandle BeginConnect返回的结果来等待一段时间。
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.
        }
    }
}

我也可以工作 :-) - jreichert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接