つまり、サーバーが 1 秒あたり 1k しか処理できない場合、クライアントは 1 秒あたり 1M を送信する機会を得られません。これには 2 つの理由があります。
- TCP にはスロー スタート メカニズムがあります
- TCP にはウィンドウ メカニズムがあり、TCP 接続の各側が常に相手側に受信能力をアドバタイズします。
クライアントがアドバタイズされたウィンドウ サイズを超えるデータを送信しても意味がありません。これは、サーバーが最初にウィンドウ サイズ外のセグメントをすべてドロップするため、クライアントはウィンドウ サイズを無視した場合に再送信する必要があるためです。ウィンドウサイズ。
バッファはさまざまなレイヤーに配置されています。ソケット オプションで設定できるバッファはソケット レベルのバッファであり、TCP ウィンドウ サイズを直接制御することはできません。これらのバッファを設定しない場合、ソケット レベルでデフォルトのバッファ サイズが取得されます。TCP は、ウィンドウ サイズ内にある順不同のパケットが受信されるかどうかに応じてキューイングします。順序どおりのデータを受信すると、ソケット レベルがトリガーされ、データがソケット レベル バッファにプッシュされ、使用可能なスペースの量だけプッシュされます。TCP が受信したすべてのデータをソケット バッファにプッシュできない場合、これは TCP ウィンドウ サイズを計算するアルゴリズムに影響を与えます。この計算メカニズムは、TCP バッファに残っているバイト数に基づいています。
サーバーもクライアントも、誰もクラッシュしません。
高速で送信できるクライアント側では、TCP がサーバーのアドバタイズされたウィンドウ サイズに基づいて、ネットワーク上に多くのデータを送信できないことがわかるため、同様のことが起こります。そのため、クライアントの送信バッファがいっぱいになります。満杯の場合、クライアント ソケットは送信時にブロックするか (ブロッキング モード)、ブロックすることを示すエラー メッセージを返します (非ブロッキング モード)。
したがって、これは何が起こるかを説明するだけではなく、なぜそれらのことが起こるのか、どのように実装されるのかについても説明しようとしました。