2017-04-19 13 views
0

UDP(1036バイトのデータグラムサイズ)経由で最大900 Mb/sのデータを受信するアプリケーションを開発しています。 「通常の」状況(システムの負荷やユーザーの操作なし)では、すべて正常に動作します.OSによって報告されたデータグラムもアプリケーションによって報告されません。 Windowsエクスプローラのフォルダツリーをクリックしてメイン表示ウィンドウの内容を変更すると、データグラムが削除されます。 Windowsパフォーマンスモニタを使用し、データグラムのペイロードに焼いたシーケンス番号を確認することで、これを観察します。 これは、クリックするたびに数百のデータグラムが失われるようになります。Windowsエクスプローラウィンドウを操作するとUDPパケットが破棄される

レシーバのバッファサイズが増えました(128 MBのOS、それ以上のアプリケーション)。

ioctlsocket(my_socket, FIONREAD, &readableBytes); 

が正確なバイト数を返す場合、バッファーは限界に達しないことをさらに観察します。最も高い観測値は2 MB未満です。 他のどのバッファがオーバーフローしているのか、その状態を追跡する方法がわかりません。

アプリケーションはQtを使用して開発されています。 UDP受信スレッドの他に、3つの他のスレッドが使用されています。ユーザインタラクションがなく、受信スレッドが切断されている場合、それらはすべてアイドルです。このすべては、問題を再現するすべてのテスト設定の場合です。

受信スレッドの最初の反復では、Qt UDPソケットが使用され、正しいシーケンス番号が確認されました。

2回目の反復では、別のスレッドで実行されたシーケンス番号のチェックとともに、プレーンなWinSock呼び出しrecv(...)を使用しました。これは明らかにスレッドの量を増加させました。両方のスレッドはロックフリーキューを介して通信しています。ロックキューは、それに提示された読み書き操作を完全に処理できます。それにもかかわらず、受信側スレッドだけが実行中であっても(データグラムの読み取りと破棄)、上記と同じ動作が観察されることがあります。

複数の受信スレッドを持つ実装(読み込みと破棄のみ)でも同じ動作を示します。

データレートが330 Mb/sに低下しても問題は発生する可能性がありますが、それほど頻繁には発生しません。さらに低いデータレートでは消えます。

はい私はUDPが配信を保証していないことを知っていますが、パケットは明らかに私のマシンに届いており、十分なCPU時間と使用可能なバッファスペースで破棄されます。私が知りたいのは何

  1. この挙動のいずれかの説明がありますか?
  2. もしそうなら、可能な解決策は何でしょうか?
  3. そうでない場合は、この問題の原因を調べるために何が確認できましたか?

お手数ですが、ありがとうございます。

答えて

2

簡単な説明は、入力ストリームの後ろにひどく遅れているということです。あなたが1kbのパケットを持っている場合、バッファされたデータの2MBの価値は巨大ですです! UDPは、古いデータではなく、現在のデータを提供するように設計されています。リアルタイムで2000パケット遅れている場合、ネットワークスタックはパケットを破棄してパケットの廃棄を開始します。それはまったく予想通りです。おそらく、最悪の場合、数千ではなく、数十パケット先になるはずです。

多くの優先度の高いスレッドに分散した最新のオーバーラップI/Oを使用するようにコードを書き直す必要があります。理想的には、ネットワークスタックによって直接満たされるノーコピーパケットバッファを使用します。

Qtはこれを抽象化するとより良い仕事をすることができますが、誰かがそれを実装するまでは、Windows上の最新の高性能ネットワーキングについて読むことができます。

+0

UDPは、現在のデータだけでなく、どのデータにも使用できます。例えば、トレントプロトコルは転送のためにそれを使用し、定義上、現在のデータはありません。 –

+0

私はおそらく循環的に "最新の"パケットを使用して、直前に到着したものよりはるかに遅れていないパケットを意味します。パケットは固定レートで到着すると仮定します。その場合、受信バッファの充填は、明らかに、受信コードがデータレートに対処できないことに起因する。このようなパケットを保持する必要はなく、キューは拡大するだけなので、ドロップする必要があります。 2MBは、ギガビットリンク上で〜22ms相当のデータです。 –

+0

答えをありがとう!私はあなたが重複したI/OモードでWSARecvを使用することを意味すると仮定します。 –

関連する問題