端口扫描器慢

时间:2012-06-24 20:28:18

标签: c# .net sockets

我在C#中创建了一个端口扫描程序,但我似乎无法让它更快:

private void Scan()
{
    int startPort = Convert.ToInt32(txtFrom.Text);
    int endPoint = Convert.ToInt32(txtTo.Text);

    progressBar1.Value = 0;
    progressBar1.Maximum = endPoint - startPort + 1;

    for (int currPort = startPort; currPort <= endPoint; currPort++)
    {
        TcpClient tcpportScan = new TcpClient();
        tcpportScan.SendTimeout = 10;
        try
        {
            tcpportScan.Connect(txtIPaddress.Text, currPort);
            txtDisplay.AppendText("Port " + currPort + " open.\n");
        }
        catch (Exception)
        {
            txtDisplay.AppendText("Port " + currPort + " closed.\n");
        }
        progressBar1.PerformStep();
    }
}

有谁知道如何加快这个过程?

3 个答案:

答案 0 :(得分:2)

在请求被视为失败之前,创建连接会受到超时限制,这使得您的scannig变得如此之慢。使用异步代码和/或多个线程来加快速度。

答案 1 :(得分:1)

以下C#4代码将并行扫描端口,并在其中一个扫描完成时通知UI。

每次扫描都由ScanSinglePortTask方法执行,该方法启动扫描并返回字符串结果并显示消息。每个任务都以LongRunning选项开始,以通知运行时并行运行大量任务是正常的,因为每个操作都需要很长时间。

每次扫描后,在UI线程上运行的新任务将使用TaskScheduler.FromCurrentSynchronizationContext更新消息和进度条。

ToArray调用是强制枚举LINQ查询并启动任务所必需的。任务数组可以与Task.Factory.ContinueWhenAll一起使用,以在扫描完成后运行一些其他代码,例如。更新忙碌指标

    private void ScanP()
    {
        int startPort = Convert.ToInt32(txtFrom.Text);
        int endPoint = Convert.ToInt32(txtTo.Text);

        progressBar1.Value = 0;
        progressBar1.Maximum = endPoint - startPort + 1;


        var scans = from i in Enumerable.Range(startPort, 
                                               endPoint - startPort + 1)
                    select ScanSinglePortTask(i)
                        .ContinueWith(t => Report(t.Result),
                            TaskScheduler.FromCurrentSynchronizationContext());
        var tasks=scans.ToArray();

    }

    private Task<string> ScanSinglePortTask(int currPort)
    {
        return Task.Factory.StartNew(() =>
            {
                try
                {
                    using (var tcpportScan = new TcpClient())
                    {
                        tcpportScan.SendTimeout = 10;
                        tcpportScan.Connect(txtIPaddress.Text, (int) currPort);
                    }
                    return "Port " + currPort + " open.\n";
                }
                catch (Exception)
                {
                    return "Port " + currPort + " closed.\n";
                }
            }, TaskCreationOptions.LongRunning);
    }

    private void Report(object message)
    {
        txtDisplay.AppendText((string)message);
        progressBar1.PerformStep();
    }

答案 2 :(得分:0)

尝试使用parallel.foreach / for循环。这会快得多。

    Parallel.For(0, 100, d =>
    {
        // Do processing here
        // d is the equivalent to i in a standard for loop             
    });



   List<int> numbers = new List<int>();
   Parallel.ForEach(numbers, n =>
       {
        // Do Processing here
        // n is the current item 
    });

以下是我的博客链接,其中包含更多详细信息。

http://tsells.wordpress.com/2011/03/03/using-parallel-for-and-foreach-loops-in-net-4-2/