0

我在 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();
    }
}

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

4

3 回答 3

2

在请求被视为失败之前,创建连接会超时,这就是让您的扫描如此缓慢的原因。使用异步代码和/或多线程来加快速度。

于 2012-06-24T20:30:39.683 回答
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();
    }
于 2012-06-25T12:34:12.353 回答
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/

于 2012-06-25T00:56:29.690 回答