2017-12-30 93 views
0

私はC#で単純なポートスキャナを構築しています。私は既にポートスキャン機能を持っており、ユーザーは使用するスレッド数とIPアドレスの範囲を渡します。だから、私は現時点で範囲を解析し、範囲内のすべてのIPアドレスを含むConcurrentBagを作成したことになります。私もスレッドの配列を持っています。CでスレッドとConcurrentBagを使用

var ipsInRange = IPAddressRange.Parse(range); 

Thread[] hostThreads = new Thread[(int)threads]; 
ConcurrentBag<IPAddress> ips = new ConcurrentBag<IPAddress>(); 
foreach (var ip in ipsInRange) 
{ 
    ips.Add(ip); 
} 

IPAddress address; 
while (!ips.IsEmpty) 
{ 
    if (ips.TryTake(out address)) 
    { 
     PortScanner ps = new PortScanner(address); 
     ps.Scan(); 
    } 
} 

// I want to assign each thread one IP address, create a new PortScanner 
// instance as above, and scan the IP. I want to delete the scanned IPs 
// from the bag. When the thread finishes with scanning, I want to assign 
// a new one to it. I want to continue like this until the bag is empty, 
// i.e. all the IPs are processed. 
// So, simply I want to scan multiple IPs at the same time, using the above 
// thread array and the ConcurrentBag containing list of IPs. 

けれども、私は前ThreadsConcurrentBagを使用していない、と私はコメント欄で上に書かれている達成したい:だから、それは部分的にこのようになります。任意のアイデアどのように私はアプリに上記のスレッドを組み込むことができますか?

+0

マルチスレッドネットワークプログラミングに関するリソースを検索し、自分自身を教育するのに役立ちます。 –

答えて

2

私は自分自身をTask Parallel Libraryを使用してのではなく、スレッドを管理することをお勧めします。短いコードと読みやすいコードにつながり、スレッドも、ConcurrentBagも処理する必要はありません。

すべてのIPアドレス(すなわち、あなたがポートスキャン時にIPアドレスを追加/削除する必要はありません)ポートスキャンが始まる前に知られている場合、コードはこのような単純なものができます:

var ipsInRange = IPAddressRange.Parse(range); 

var options = new ParallelOptions() 
{ 
    MaxDegreeOfParallelism = 5// Set number of IP addresses to be processed concurrently 
}; 

Parallel.ForEach(
    ipsInRange, 
    options, 
    (address) => { PortScanner ps = new PortScanner(address); ps.Scan(); }); 

あなたが必要な場合ポートスキャンの進行中にIPアドレスのリストを(他のスレッドから)変更できるシナリオをサポートするには、ipsInRangeコレクションをBlockingCollectionにラップする必要がありますが、質問からは必要ないと思われます。

1

私は解決策を見てのとおり:

  1. がcoolectionからIPをとること、いくつかのタスクを作成
  2. IP-アドレスを持つblocking collectionを作成し、それをスキャンします。

    var bc = new BlockingCollection<string>(); 
    //... 
    bc.Add(ip); //add addresses from another thread, or smth else 
    //... 
    
    for(int i = 0; i < 10; i++) 
    { 
        Task.Run(()=> 
        { 
         var address = bc.Take(); 
         PortScanner ps = new PortScanner(address); 
         ps.Scan(); 
        }); 
    } 
    

あなたはアドレスをスキャンする10個のスレッドを、持っているコレクションは彼らに次の要素を与えることができますが、彼らは、待機します。

+0

答えをありがとう。私はこれを試みたが、明らかにそれは動作しません。私はそれがforループを実行することに気づいたが、単に 'i'をインクリメントして出て行く。 'Task.Run'部分に来て、その中のすべてをスキップします。何が欠けているのか? – tinker

+0

@tinkerそれはスキップしません。それは新しいスレッドを起動し、 'Run'メソッド内でコードを実行します – Backs

+0

非常に迅速に終了し、何もコンソールには印刷されませんが、通常はプログラムを実行するとコンソールに印刷されます。第二に、もし私がブレークポイントを置くと、 'address'で言うと、そこに止まらないということです。以前はあなたと同様のコードを実行していましたが、 'List 'を使い、最後に 'Task.WaitAll()'を実行していました。もう一度やり直して、コンソールに物を印刷しました。 – tinker

関連する問題