TCPと信頼性 — ロスを隠して「届いたことにする」
IPは「たぶん届く」ベストエフォート。パケットは落ちるし、順番も入れ替わります。その上に乗って「確実に・順番どおり」届いたように見せるのがTCPです。接続を開く3ウェイハンドシェイク、まとめて送るスライディングウィンドウ、落ちたら送り直す再送、届いた順を直す受信バッファ ― 信頼性の4つの仕掛けを動かして見ていきます。
1. コネクションを開く — 3ウェイハンドシェイク
いきなりデータを送りつけるのではなく、TCPはまずお互いに「準備OK」を確認してから通信を始めます。使うのは3通のメッセージ。各自が自分のシーケンス番号(SEQ)の初期値を相手に伝え、相手はそれをACK(確認応答)で「受け取った、次はこの番号ね」と返します。
「1ステップ進める」で1通ずつ、状態(CLOSED→…→ESTABLISHED)が変わる様子を追ってください。
2. 一度にたくさん送る — スライディングウィンドウ
1通送るたびにACKを待っていたら、往復時間(RTT)ぶん毎回止まって遅すぎます。そこでTCPはACKを待たずに送ってよい量=ウィンドウを決め、その範囲のセグメントをまとめて送信。ACKが返ってきたぶんだけウィンドウが右へスライドし、新しいセグメントを送れます。
ウィンドウサイズを変えて、同時に「飛んでいる」セグメントの数と、ACKが窓を押し出す様子を見てください。
3. 失われたら送り直す — 再送
ネットワークではパケットが落ちます。TCPはACKが返ってこないことを手がかりにロスを検知し、再送します。きっかけは2つ ―(1)一定時間ACKが来ないタイムアウト、(2)後続は届いているのに1つだけ欠けたときに受信側が繰り返す重複ACK。重複ACKが3回続くと、タイムアウトを待たず即座に送り直すファストリトランスミットが発動します。
ロス率を上げて、パケットが途中で消える→タイムアウト→再送、の流れを観察してください。
4. バラバラに届いても直す — 順序保証と受信バッファ
パケットは別々の経路を通ったり再送されたりで、送った順とは違う順で届くことがあります。TCPは各セグメントのシーケンス番号を見て、受信側のバッファにいったん並べ、先頭から連続してそろったぶんだけアプリに渡します。欠けている番号があると、後ろがそろっていても待たされます(ヘッドオブラインブロッキング)。
5. まとめ — 信頼性は4つの仕掛けの合わせ技
- 3ウェイハンドシェイク:双方向のSEQを交換・確認してから通信開始。
- スライディングウィンドウ:ACKを待たずまとめて送り、返ったぶん窓が進む。速さの源。
- 再送:タイムアウトと重複ACK×3で欠けを検知し、送り直す。
- 順序保証:シーケンス番号でバッファに並べ、連続したぶんだけアプリへ。