2

さまざまな着信ポート (~20) からの UDP パケットをリッスンしようとしています。これらのパケットの受信と処理に 3 ~ 5 個のスレッドを割り当てたいと考えています。これは、Windows の IO 完了ポートにとって理想的な状況のようです。私が理解していないのは、複数のソケットの多対少数のマッピングを実行して、より小さなスレッドセットをチェックする方法です。

次のコードは、すべてのソケットを作成し、非同期受信操作を開始します。

for(int ix = 0; ix < 20; ix++)
{
    var socket = new Socket(AddressFamily.InterNetwork,
                            SocketType.Dgram, ProtocolType.Udp);
    socket.Bind(new IPEndPoint(IPAddress.Any, ix+6000));
    var e = new SocketAsyncEventArgs();
    e.Completed+=OnReceive;
    e.SetBuffer(buffer, ix*1024*1024, 1024*1024);
    socket.ReceiveFromAsync(e);
    _sockets.Add(socket);
}

パケットが受信されると、各 OnReceive Message が呼び出されることを理解しています...

static void OnReceive(object sender, SocketAsyncEventArgs e)
{
    Console.WriteLine("Received {0} bytes", e.BytesTransfered);
    if(!((Socket)sender).ReceiveFromAsync(e))
        e_Completed(sender, e);
}
  1. OnReceive イベントを実行するスレッドの数を制限するにはどうすればよいですか?
  2. OnReceive メソッドが再帰的に何度も自分自身を呼び出すというまれなケースで、スタック オーバーフローを防ぐ最善の方法は何ですか?
4

1 に答える 1

0

受信と処理のためのスレッドの意味がわかりません。受信はバックグラウンドで行われます。

とにかく、BlockingCollectionを使用します。

OnReceiveは次のようになります

private static BlockingCollection<byte[]> _received = new ...

static void OnReceive(object sender, SocketAsyncEventArgs e) {
    byte[] data = new byte[e.BytesTransfered];
    Array.Copy(e.buffer, e.Offset, data, 0, e.BytesTransfered);
    _received.Add(data)
    ...
}

次に、TPL / PLinqを使用して、要求された数のスレッドで受信したデータを処理します。

var parallelOptions = new ParalellOptions { MaxDegreeOfParallelism = 3 };
Parallel.ForEach(_received.GetConsumingPartitioner(),
                parallelOptions, 
                data => {
                    // do processing
                    ...
                });
于 2012-09-27T07:29:45.797 に答える