0

私は経験豊富なネットワーク プログラマーであり、アドバイスが必要な状況に直面しています。

いくつかのデータをいくつかの発信インターフェイスに配布する必要があります (それぞれが各インターフェイスに対応する異なる TCP ソケット接続を介して)。ただし、重要な部分は、より良い帯域幅、つまりより高速に送信できるインターフェイスで、より多く/ほとんどのデータを送信できる必要があるということです。

私が持っていた意見は、この目的のために選択 API (UNIX と Windows の両方) を使用することでした。過去にselect、poll、さらにはepollを使用したことがあります。ただし、データが利用可能な場合は常に、複数のソケットから読み取るためのものでした。

ここでは、いくつかのインターフェイスに連続したパケットを順番に書き込み、それぞれの書き込み記述子を監視し (パラメーターを選択)、利用可能な方 (最初にパケットを送信できたことを意味します) を介して、より多くのパケットを送信し続けます。その記述子。

ここで私の意図を達成することはできますか?つまり、10Mbps リンクのインターフェイスと 1Mbps の別のインターフェイスがある場合、より高速なインターフェイスを介してほとんどのパケットを取得できることを願っています。

更新 1:この場合、選択の動作はどうなるのだろうと思っていました。つまり、読み取り記述子で選択を呼び出すと、データが利用可能な記述子が返されます。ただし、私のシナリオでは、ディスクリプタに書き込んでいて、select が最初に書き込みを終えたものを返すのを待っているとき、select は、パケット全体が書き込まれた場合にのみ戻ることを保証します。つまり、一度に 1200 バイトを書き込もうとしたとします。1200全体が返された場合にのみ返されますか、それとも永続的なエラーがありますか? select がどのように動作するかはわかりませんが、それを説明するドキュメントが見つかりませんでした。

4

2 に答える 2

1

書き込みに使用poll/epoll/selectするのはかなりトリッキーです。その理由は、ソケット送信バッファーがいっぱいでない限り、ソケットはほとんど書き込みの準備ができているためです。そのため、「書き込み可能」のポーリングは、待機せずにスピンする傾向があります。

次のように進める必要があります。

  1. ソケットに書き込むものがある場合は、すべてのデータが書き込まれたときに終了する write()、 で-1 を返すループで書き込みますerrno == EAGAIN/EWOULDBLOCK

  2. その時点で、完全なソケット送信バッファーがあります。したがって、書き込み可能にするために、このソケットを selector/poll/epoll に登録する必要があります。

  3. 他に何もすることがない場合は、select/poll/epoll を実行して、関連するソケットが書き込み可能かどうかポーリングされる原因となった書き込みを繰り返します。

  4. これらの書き込みは (1) と同じ方法で行いますが、今度は、書き込みが完了したら、書き込み可能にするためにソケットの登録を解除します。

つまり、ソケットの送信バッファがいっぱいであることがすでにわかっている場合にのみ、書き込み可能性を選択/ポーリングする必要があり、そうではないことがわかったらすぐに停止する必要があります。

これらすべてをアプリケーションにどのように適合させるかは、別の問題です。

于 2013-06-14T02:30:58.210 に答える
1

プロデューサー/コンシューマーのパターンを適応させます。この場合、1 つのプロデューサーと複数のコンシューマーです。

メイン スレッドでソースを処理し (プロデューサー)、接続ごとに 1 つのスレッドを生成します (コンシューマー)。

並列のスレッドは、ソースのチャンクをそれぞれプルし、接続を介して 1 つずつ送信します。

最速の接続を保持しているスレッドは、この設定で最も多くのチャンクを送信すると予想されます。

于 2013-06-13T11:41:06.387 に答える