15

アプリケーションで TCP ウィンドウ サイズを大きくすることに疑問があります。私の C++ ソフトウェア アプリケーションでは、TCP/IP ブロッキング ソケットを使用してクライアントからサーバーに約 1k のサイズのデータ​​ パケットを送信しています。最近、この概念 TCP Window Size に出くわしました。setsockopt()そこで、 for と の両方SO_SNDBUFを使用して、値を 64K に増やしてみましたSO_RCVBUF。この値を増やした後、LAN 接続ではなく、WAN 接続のパフォーマンスが向上しました。

TCPウィンドウサイズでの私の理解によると、

クライアントはデータ パケットをサーバーに送信します。この TCP ウィンドウ サイズに達すると、ウィンドウ サイズの最初のパケットに対する ACK がサーバーから受信されたことを確認するために待機します。WAN 接続の場合、RTT で約 100 ミリ秒の遅延が発生するため、サーバーからクライアントへの ACK が遅延します。したがって、この場合、TCP ウィンドウ サイズを大きくすると、ACK 待機時間が補償され、パフォーマンスが向上します。

アプリケーションのパフォーマンスがどのように向上するかを理解したいと考えています。

私のアプリケーションでは、ソケット レベルを使用して TCP ウィンドウ サイズ (送信バッファと受信バッファの両方) を増やしてsetsockoptも、1k の同じパケット サイズを維持します (つまり、単一のソケット送信でクライアントからサーバーに送信するバイト数)。また、Nagle アルゴリズムを無効にしました (小さなパケットを大きなパケットに統合する組み込みオプションで、頻繁なソケット呼び出しを回避します)。

私の疑問は次のとおりです。

  1. ブロッキングソケットを使用しているため、1k のデータパケット送信ごとに、ACK がサーバーから来ない場合はブロックする必要があります。では、WAN 接続だけで TCP ウィンドウ サイズを改善すると、どのようにパフォーマンスが向上するのでしょうか。TCP ウィンドウ サイズの概念を誤解している場合は、訂正してください。

  2. 64K のデータを送信するには、TCP ウィンドウ サイズを 64K に増やしても、ソケット送信関数を 64 回呼び出す必要があると思います (ブロッキング ソケットを介して送信ごとに 1K を送信しているため)。これを確認してください。

  3. RFC 1323 アルゴリズムでウィンドウ スケーリングが有効になっている場合の TCP ウィンドウ サイズの最大制限は?

私は英語があまり得意ではありません。上記の内容でわからないことがあれば、教えてください。

4

2 に答える 2

34

まず第一に、あなたの質問から明らかな大きな誤解があります.TCPウィンドウサイズは と によって制御されるものSO_SNDBUFですSO_RCVBUF。本当じゃない。

TCP ウィンドウ サイズとは何ですか?

簡単に言えば、TCP ウィンドウ サイズは、まだ確認されていない最初のパケットの確認を受信する前に、ネットワーク スタックがネットワーク上に置くことをいとわないフォローアップ データ (パケット) の量を決定します。

TCP スタックは、送信中にパケットが失われたか破損したと判断されると、それ以降に送信されたすべてのパケットを再送信する必要があるという事実に対応し、説明する必要があります。受信機によって。したがって、あまりにも多くの未確認パケットが同時に存在することを許可すると、接続の帯域幅が投機的に消費されます。使用される帯域幅が実際に有用なものを生成するという保証はありません。

一方、複数の未確認パケットを同時に許可しないと、帯域幅と遅延の積が高い接続の帯域幅が単純に失われます。したがって、TCP スタックは、帯域幅を無駄に使い切ることと、パイプを十分に積極的に駆動しないこと (したがって、その容量の一部が未使用になることを許可すること) の間でバランスを取る必要があります。

TCP ウィンドウ サイズによって、このバランスがどこで決まるかが決まります。

何をしSO_SNDBUF、何をSO_RCVBUFしますか?

それらは、ネットワーク スタックがソケットにサービスを提供するために予約したバッファ スペースの量を制御します。これらのバッファは、スタックがまだネットワーク上に置くことができなかった送信データと、ネットワークから受信されたがまだアプリケーションによって読み取られていないデータをそれぞれ蓄積するのに役立ちます。

これらのバッファの 1 つがいっぱいになると、スペースが解放されるまでデータを送受信できなくなります。これらのバッファは、ネットワーク スタックがネットワーク インターフェイスの「近い」側 (送信前または到着後) でデータを処理する方法にのみ影響することに注意してください。一方、TCP ウィンドウは、スタックが「遠い」側でデータを管理する方法に影響します。インターフェイスの側 (つまり、ワイヤ上)。

ご質問への回答

  1. いいえ。その場合、送信されるパケットごとにラウンドトリップ遅延が発生し、遅延の大きい接続の帯域幅が完全に破壊されます。

  2. はい。ただし、TCP ウィンドウ サイズまたはそのソケットに割り当てられたバッファのサイズとは関係ありません。

  3. 私が見つけたすべての情報源 ( example ) によると、スケーリングにより、ウィンドウは最大 1GB のサイズに達することができます。

于 2013-01-17T14:55:39.227 に答える
1
  1. ブロッキングソケットを使用しているため、1k のデータパケット送信ごとに、ACK がサーバーから来ない場合はブロックする必要があります。

違う。TCP での送信は非同期です。send() は、データをソケット送信バッファに転送して返すだけです。ソケット送信バッファがいっぱいの間だけブロックします。

では、WAN 接続だけで TCP ウィンドウ サイズを改善すると、どのようにパフォーマンスが向上するのでしょうか。

ACKを受け取るまでブロックするのは間違っていたからです。

  1. 64Kのデータを送信するには、ソケット送信関数を64回呼び出す必要があると思います

なんで?64k データ バッファで 1 回だけ呼び出すことができます。

(ブロッキングソケットを介して送信ごとに1kを送信しているため)

なんで?それとも(1)の誤解の繰り返しですか?

TCP ウィンドウ サイズを 64K に増やしたにもかかわらず。これを確認してください。

いいえ、まとめて送信できます。ループは必要ありません。

RFC 1323 アルゴリズムで Windows スケーリングが有効になっている場合の TCP ウィンドウ サイズの最大制限は?

必要以上に大きくなります。

于 2013-01-31T23:07:35.143 に答える