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 コードは、ポートを並行してスキャンし、スキャンの 1 つが完了するたびに UI に通知します。

各スキャンは ScanSinglePortTask メソッドによって実行されます。このメソッドはスキャンを開始し、表示するメッセージを含む文字列の結果を返します。各タスクは、LongRunningオプションで開始され、各操作には時間がかかるため、多くのタスクを並行して実行しても問題ないことをランタイムに通知します。

各スキャンの後、UI スレッドで実行される新しいタスクは、TaskScheduler.FromCurrentSynchronizationContextを使用して、メッセージと進行状況バーを更新します。

ToArray 呼び出しは、LINQ クエリの列挙を強制してタスクを開始するために必要です。tasks 配列を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 に答える