3

WinSock send 呼び出しで 200ms 遅延する可能性があることがわかりました

MSDN から: http://support.microsoft.com/kb/214397/en

Nagle アルゴリズム: http://en.wikipedia.org/wiki/Nagle 's_algorithm

問題の概要:

SO_SNDBUF オプション「0」で small msg(< MTU)を繰り返し送信する場合は、ファンクションブロックを 200ms 送信する。

私の質問:最初にメッセージを送信するのに 200 ミリ秒かかるのはなぜですか?

TCP は最初の送信呼び出しの前にアイドル状態になっているため、最初のメッセージはすぐに送信する必要があると思います。

しかし、テスト結果は望ましくありません。

最初のメッセージも 200 ミリ秒遅れましたが、なぜですか?

回答ありがとうございます。

詳細を追加します

Naggle アルゴリズムは、次のような小さなメッセージに対して機能します。

1. if wire is idle, send it immediately.
2. if formal message's ACK is not received, wait until ACK & send
3. Window's TCP ack delay mechanism send ack after 200ms.

したがって、私の予想では、最初のメッセージはすぐに送信され、2 番目のメッセージは最初のメッセージの ack を 200 ミリ秒待機します。

これは間違っていますか?

4

4 に答える 4

4

通常、TCP は、ピアによって ack されるまで、データを送信バッファーに保持します。あなたの場合、送信バッファはありません(SO_SNDBUF = 0のため)。そのため、TCP は、再送信の可能性に備えてデータを保持するために送信者をブロックします。ピアの TCP スタックは "Delayed ack" ルーチンを使用し、200ms の遅延の後 (または ack なしでデータを含む 2 つのパケットが受信されるまで) 確認応答を送信します。

したがって、すべてのデータがピアによって確認されるまで、送信者はブロックされます。ネットワークのRTTが長い場合や、パケットロスが発生した場合、200ms以上かかる場合があります。

于 2012-07-12T08:58:50.440 に答える
3

遅延の要点は、同じメッセージに追加できるデータがさらに来るかどうかを確認することです。最初のメッセージをこの規則の例外にする理由はありません。

于 2012-07-12T08:45:48.697 に答える
3

Nagle アルゴリズムの背後にある考え方は、次のようなケースを最適化することです。

  1. send() 呼び出し内で 1 バイトのデータを送信します
  2. 1ミリ秒後、1バイトのデータでsend()を再度呼び出します
  3. さらに 1 ミリ秒後に、再度 send() を呼び出します。

Nagle アルゴリズムがないと、それぞれ数バイトのヘッダーと 1 バイトの有用なペイロードしか持たない 3 つの個別のパケットが生成されます。それは、多くのオーバーヘッドを意味します。

Nagle アルゴリズムでは、send() 呼び出しの同じシーケンスで、いくつかのヘッダー バイトと 3 バイトのペイロードを含む 1 つのパケットのみが生成されるため、オーバーヘッド サイズが削減されます。ただし、パケットは最初の呼び出しから 200 ミリ秒後に送信されます。

Nagle アルゴリズムの考え方は、データの小さなチャンクを送信した後、おそらくさらに送信する必要があることを期待して待機することです。システムは、送信に関する将来の計画を認識していないため、適切な時間 (200 ミリ秒) 待機し、それ以上送信されない場合は、遅延が大きくなりすぎないように実際のパケットを送信します。

応答を待たずに小さなチャンクでデータを送信する場合 (たとえば、テキスト ファイルを 1 行ずつ送信する場合)、このアルゴリズムはプログラムに役立ちます。これにより、ネットワーク経由で送信されるパケットの量と関連するオーバーヘッドが大幅に削減されます。

プログラムが応答時間に敏感で、この最適化を必要としない場合は、TCP_NODELAY 引数を指定して setsockopt() を呼び出して安全に無効にするか、TCP の代わりに UDP を使用することを検討してください。

于 2012-07-12T10:01:20.007 に答える
0

正直なところ、最初のメッセージも遅延するような動作は覚えていません。私は WinSock で作業しましたが、データはスムーズに動作していました。これはどの標準にも違反していないため、この方法で実装できます。これが答えです。

于 2012-07-12T08:31:52.640 に答える