TCP受信バッファとTCPウィンドウサイズ
TCP受信バッファとは、OS(Linuxカーネル)がソケット単位で確保するメモリ領域であり、ネットワークから届いたデータを一時的に保持し、アプリケーションが読み取るまで保管する役割を担います。この受信バッファは通信状況に応じて動的にサイズが調整されます。
受信側は、TCP受信バッファの空き容量に応じて「ウィンドウサイズ(送信可能なデータ量)」を送信側に通知します。送信側はこのウィンドウサイズを基に、指定された範囲内でデータを送信します。
ただし、ウィンドウサイズはバイト単位で表されるため、実際の送信は MSS(最大セグメントサイズ)に従って分割された複数のTCPパケットとして行われます。つまり、1ラウンドトリップ(RTT)において送信されるのは「1ウィンドウサイズ分のデータ」であり、その内訳は複数のTCPパケットで構成されます。
ウィンドウサイズはバイト単位で表され、送信側はMSS(最大セグメントサイズ)に従って分割された複数のTCPパケットとして送信します。1RTT内で送信可能な最大量はウィンドウサイズに制限されますが、実際の送信タイミングはACK応答や輻輳制御アルゴリズムにも依存します。
このように、TCPは受信バッファの空き状況を反映したウィンドウサイズを用いて、送信側のデータ量を制御し、ネットワークの輻輳やバッファオーバーフローを防いでいます。

(補足)
・MSS ≒ MTU - IP/TCPヘッダ(通常1460バイト)
・ウィンドウサイズが大きいほど、1RTTあたりのスループットが向上
・アプリがデータを読み取ると受信バッファが空き、次のウィンドウサイズ通知で送信が再開される
輻輳とは
- 定義:ネットワーク内でトラフィックが過剰になり、ルータやスイッチのバッファがあふれ始める状態。
- 現象:
- パケット遅延が増える
- バッファオーバーフローによるパケットロスが発生
- 再送が増えてさらに混雑が悪化する「輻輳崩壊 (congestion collapse)」に至ることもある
Linuxカーネルにおける TCP受信バッファサイズ(ウィンドウサイズの)の確認方法
以下コマンドで最小値 / デフォルト値 / 最大値 が表示されます
sysctl net.ipv4.tcp_rmem
# 現在の値を確認
[root@vm105 ~]# sysctl net.ipv4.tcp_rmem
net.ipv4.tcp_rmem = 4096 131072 6291456
[root@vm105 ~]#
最小値 (4096) 新しいソケットに割り当てられる初期の受信バッファサイズ。
デフォルト値 (131072) 通常の通信で使われる標準的なサイズ。
最大値 (6291456) カーネルの「オートチューニング機能」によって必要に応じて拡張される上限。
TCPウィンドウサイズの変更方法
sysctl -w net.ipv4.tcp_rmem="4096 2097152 16777216"
# 設定変更
[root@vm105 ~]# sudo sysctl -w net.ipv4.tcp_rmem="4096 2097152 16777216"
net.ipv4.tcp_rmem = 4096 2097152 16777216
# 設定値の確認
[root@vm105 ~]# sysctl net.ipv4.tcp_rmem
net.ipv4.tcp_rmem = 4096 2097152 16777216
[root@vm105 ~]#
ちなみに以下のように全て同じ値を設定すると結果固定される事になります。
sysctl -w net.ipv4.tcp_rmem="4096 4096 4096"
永続化する場合
# 永続化する場合は /etc/sysctl.conf に追記
net.ipv4.tcp_rmem = 4096 87380 33554432
