10

WindowsでUDPセットアップを介したクライアント/サーバー通信システムがあります。私たちが直面している問題は、スループットが増加すると、パケットがドロップされることです。これは、継続的にポーリングされている UDP 受信バッファーが原因で、バッファーがブロックされ、着信パケットがドロップされていることが原因であると考えられます。このバッファを読み取ると、着信パケットがドロップされる可能性はありますか? もしそうなら、これを修正するためのオプションは何ですか? システムは C で書かれています。これがあいまいすぎる場合はお知らせください。詳細情報を提供できるよう努めます。ありがとう!

4

6 に答える 6

12

Windowsソケットのデフォルトのソケットバッファサイズは8k、つまり8192バイトです。バッファのサイズを増やすには、 setsockopt Windows関数を使用します(SO_RCVBUFオプションを参照)。

ただし、それを超えると、受信バッファのサイズを大きくしても、パケットを十分に速く読み取っていない場合に、パケットが再びドロップされるまでの時間が遅れるだけです。

通常、この種の状況では2つのスレッドが必要です。

最初のスレッドは、ソケットにサービスを提供するためだけに存在します。つまり、スレッドの唯一の目的は、ソケットからパケットを読み取り、それをある種の適切に同期された共有データ構造に追加し、パケットが受信されたことを通知してから、次のパケットを読み取ることです。

2番目のスレッドは、受信したパケットを処理するために存在します。最初のスレッドがパケットを受信したことを通知するまで、アイドル状態になります。次に、適切に同期された共有データ構造からパケットをプルして処理します。その後、再び信号が送られるのを待ちます。

テストとして、パケットの完全な処理を短絡して、パケットが受信されるたびにコンソール(またはファイル)にメッセージを書き込むようにしてください。パケットをドロップせずにこれを正常に実行できる場合は、機能を「受信」スレッドと「処理」スレッドに分割すると役立ちます。

于 2009-10-02T02:55:46.500 に答える
5

はい、スタックは、バッファーがいっぱいになると、パケットを (黙って) ドロップすることができます。これは、UDP の性質の一部であり、TCP から切り替えるときに放棄する信頼性のビットの 1 つです。再試行ロジックや ACK パケットなどを追加して TCP を再発明するか (下手ですが)、SCTPのような中間のものに切り替えることができます。

スタックのバッファ サイズを増やす方法はいくつかありますが、それではほとんど意味がありません。バッファー スペースを十分に確保できるほど高速に読み取りを行っていない場合、バッファーを大きくしても、バッファー スペースが不足するまでの時間を延ばすだけです。適切な解決策は、独自のコード内でより大きなバッファーを作成し、データをスタックのバッファーからプログラムのバッファーにできるだけ早く移動することです。

于 2009-10-02T02:27:36.247 に答える
3

最初のステップでは、レシーバーのバッファー サイズを増やします。Windows は、適切なサイズの要求をすべて許可します。

それでも問題が解決しない場合は、消費コードにかなり遅い領域があるようです。たとえば、pthreads でスレッド化を使用し、プロデューサー コンシューマー パターンを利用して、着信データグラムを別のスレッドのキューに入れ、そこから消費するため、受信呼び出しがブロックされず、バッファーがいっぱいにならないようにします。

3 番目のステップでは、アプリケーション レベルのプロトコルを変更し、送信側でバッチ パケットとバッチ パケットを許可して、多数の小さなパケットの送信による UDP ヘッダー オーバーヘッドを削減します。

4 番目のステップでは、ネットワーク機器、スイッチなどをチェックして、トラフィック統計、バッファ オーバーフローなどに関する詳細な出力を得ることができます。問題がある場合は、より高速なスイッチを入手するか、障害のあるスイッチを切り替えることができます。

...参考までに、バックエンドでUDPマルチキャストトラフィックを平均で継続的に実行しています。~30Mbit/秒、ピークは 70Mbit/秒で、私のドロップ率はゼロです。

于 2009-10-02T02:59:53.980 に答える
3

このバッファを読み取ると、着信パケットがドロップされる可能性はありますか?

パケットを読み取るよりも速く到着している場合、パケットがドロップされる可能性があります。

もしそうなら、これを修正するためのオプションは何ですか?

1 つのオプションは、ネットワーク プロトコルを変更することです。TCP を使用するか、UDP を使用して確認応答と「フロー制御」を実装します。

それ以外の場合は、十分に速く/頻繁に読んでいない理由を確認する必要があります。

CPU が 100% 使用されている場合は、パケットごとの作業を減らすか、より高速な CPU を取得する必要があります (まだ行っていない場合は、マルチスレッドとより多くの CPU を使用します)。

CPU が 100% でな​​い場合は、次のことが考えられます。

  • あなたはパケットを読みます
  • リアルタイムで x ミリ秒かかるいくつかの作業を行い、その一部は他の I/O でブロックされて費やされます (したがって、CPU はビジーではありませんが、別のパケットの読み取りには使用されません)。
  • これらの x ミリ秒の間に、パケットのフラッドが到着し、一部がドロップされます

これを解決するには、スレッドを変更します。

もう 1 つの可能性は、ソケットから複数の同時読み取りを行うことです (各読み取りは、UDP パケットを受信できるバッファーを提供します)。

もう 1 つの可能性は、(O/S 固有の) 構成オプションで、ネットワーク スタックが読み取ろうとするまでバッファリングする受信 UDP パケットの数を増やすかどうかを確認することです。

于 2009-10-02T02:29:10.753 に答える
0

これについてはよくわかりませんが、Windows では、ソケットをポーリングしてパケットをドロップすることはできません。Windows は、ポーリングとは別にパケットを収集するため、ドロップが発生することはありません。

select() を使用してソケットをポーリングすると仮定していますか? 私の知る限り、ドロップを引き起こすことはできません。

于 2009-10-02T02:26:34.017 に答える
0

パケットは、ルート上のどこかで関係のないネットワーク トラフィックが増加したり、受信バッファがいっぱいになったりして失われる可能性があります。これを軽減するには、Winsock の受信バッファー サイズを増やすことができます。

基本的に、UDP は、パケットの配信が保証されておらず、配信の失敗時に送信者にエラーが返されないという意味で、信頼性の低いプロトコルです。パケット損失が心配な場合は、確認パケットを通信プロトコルに実装するか、TCP などのより信頼性の高いプロトコルに移植することをお勧めします。UDP パケットの損失を防ぐための本当に信頼できる方法は他にありません。

于 2009-10-02T02:29:02.187 に答える