シーケンス番号と再送 — TCP は届いたことをどう確かめるか
バイト 1 つ 1 つに番号を振り、ack 番号 = 次に欲しいバイトで答え合わせをする。届かなかったときの 2 つの気づき方 — 再送タイマーと重複 ACK — を区別する。
「届いたはず」をどう確かめるか
第 1 章で見たとおり、IP は失ったことを教えてくれません。それでも TCP は「必ず届く、届かなければ気づく」を約束します。仕掛けはとても素朴で、宅配便の伝票番号と受領サインに似ています。
大事なのは、番号がパケットごとではなくバイトごとに振られていることです。TCP にとってデータは「バイトの流れ」であり、セグメント(パケットに載る単位)はその流れを都合よく切った断片にすぎません。数え始めの番号を前章のハンドシェイクで合意済みなので、両者は最初から同じ物差しでバイトを数えられます。以降の例では、読みやすいように数え始めを 1000 とし、最初のデータバイトを 1001 とします。
seq = 1001 で 500 バイトのセグメントはバイト 1001〜1500 を運び、ACK は「次に欲しい」1501 を指します。番号の主役はセグメントではなくバイトです。
ack 番号 = 次に欲しいバイトの番号
キャプチャを読むうえで一番の急所が、ack 番号の解釈です。「どこまで受け取ったか」ではなく「次にどこから欲しいか」を指します。seq = 1001 から 500 バイト受け取ったら、届いた最後のバイトは 1001 + 500 − 1 = 1500 番。だから返す ack は 1501 です。
もう 1 つの急所が累積確認という性質です。ACK は「ここまでは穴なく連続で受け取った」ことしか表現できません。途中の 3001〜4000 が欠けたまま 4001〜5000 が届いても、返せる ack は 3001 のまま。届いた分は受信バッファに保管しておき、穴が埋まった瞬間に ack は一気に 5001 まで跳びます。この「保管して並べ直す」動きこそが、約束その 2「順番どおり」の実体です。
小問 3-1 — seq と ack を手計算する
キャプチャを読む力はこの計算がすべての土台です。バイトの範囲を紙に書いて確かめてください。
Q1. 送信側が seq = 1001 のセグメントで 500 バイトのデータを送りました。受信側がこれを受け取って返す ack 番号はいくつですか。
このセグメントが運ぶのはバイト 1001〜1500 の 500 バイトです(1001 + 500 − 1 = 1500)。ack 番号は「次に欲しいバイトの番号」なので、1500 の次の 1501 を返します。「受け取った最後の番号」ではなく「次に欲しい番号」— この 1 ずれを体に入れることが、キャプチャを読む第一歩です。
Q2. 受信側はバイト 3000 まで連続で受信済みです。そこへ、途中の 3001〜4000 を飛ばして 4001〜5000 のセグメントが届きました。受信側が返す ack 番号はいくつですか。
TCP の ACK は累積確認です。「ここまでは穴なく連続で受け取った」ことしか言えないので、4001〜5000 が手元にあっても、欠けている 3001 より先には進めません。届いた 4001〜5000 は受信バッファに保管され、ack = 3001 を返します。この「同じ ack を繰り返す」動きが、後半の重複 ACK の伏線です。
Q3. TCP のシーケンス番号が「セグメント(パケット)ごと」ではなく「バイトごと」に振られていることの利点はどれですか。
TCP が運ぶのはバイトの流れであって、パケットの列ではありません。再送時に複数セグメントをまとめ直したり、経路の都合で分割されたりしてセグメントの切れ目は変わりえますが、バイト単位の番号ならどう切り直しても「どこまで届いたか」が一意に決まります。この「セグメントではなくバイトが主役」という見方は、第 6 章のフレーミング問題にも直結します。
気づき方 1 — 沈黙(再送タイマー)
ACK が返ってこないとき、どれだけ待てば「失われた」と判断してよいでしょうか。短すぎれば無駄な再送でネットワークを圧迫し、長すぎればユーザを待たせます。TCP は送るたびに往復時間(RTT: 送ってから ACK が返るまでの時間)を測り続け、その平均とばらつきから再送タイムアウト(RTO)を動的に計算します。同じ建物内なら数ミリ秒、大陸間なら数百ミリ秒 — 回線に合わせて物差しが変わるのです。
RTO が満了すると欠けたセグメントを再送し、RTO を倍に延ばして次を待ちます(指数バックオフ)。ACK が返らない最有力の原因は混雑なので、送り直すほど間隔を空けて、混雑への追い打ちを避ける設計です。
気づき方 2 — 悲鳴(重複 ACK)と高速再転送
沈黙を待つより速い方法があります。バイト 8000 まで届いた後で 8001〜9000 が失われ、その後続だけが届き続けると、受信側は届くたびに ack = 8001 を返すしかありません。送信側から見ると同じ番号の ACK が繰り返し届く — これが重複 ACK です。
重複 ACK は 1 通ごとに「後続は届いたのに、8001 からの穴が埋まらない」と言っています。同じものが 3 回届いたら、送信側はもう待ちません。後続が届いている = 経路は生きている = 欠けたのはおそらく 1 つと推理し、RTO を待たずに seq = 8001 のセグメントだけを再送します。これが高速再転送です。
キャプチャで再送を見つけたら、どちらの再送かを見てください。重複 ACK 由来なら軽い単発ロス、タイムアウト由来なら応答が全く返らない深刻な状態 — 同じ「再送」でも読みは正反対です。
小問 3-2 — 届かなかったことに、どう気づくか
TCP には「届かなかった」を知る通知はありません。沈黙と重複という 2 つの間接証拠から推理します。
Q4. 再送タイマー(RTO)の説明として正しいものはどれですか。
RTO は「これだけ待って ACK が来なければ失われたと見なす」しきい値で、RTT の測定値と揺らぎから動的に決まります。近距離なら短く、遠距離なら長く。再送してもまだ ACK が来なければ待ち時間を倍々に延ばし(指数バックオフ)、混雑したネットワークへ追い打ちをかけないようにします。受信側は「届いていない」を通知できません — 届いていないものは、届いていないと気づけないからです。
Q5. 送信側に同じ ack 番号の ACK(重複 ACK)が何度も届くことがあります。受信側で何が起きていますか。
累積確認の帰結です。バイト 8000 まで受信済みで 8001〜9000 が欠けたまま後続(9001〜、10001〜…)が届くと、受信側はそのたびに ack = 8001 を返すしかありません。つまり重複 ACK は「その先は届いているのに、ここだけ欠けている」という受信側からの悲鳴です。バッファ満杯はウィンドウ 0 の広告(第 4 章)で伝えられ、これとは別物です。
Q6. 同じ重複 ACK が 3 回届いた時点で、送信側はタイムアウトを待たずに欠けたセグメントを再送します(高速再転送)。タイムアウトを待たずに送ってよいと判断できる根拠はどれですか。
重複 ACK は後続セグメントが届くたびに生まれます。つまり 3 回届いたなら、少なくとも 3 つの後続が無事に届いている — 経路は生きていて、欠けたのはおそらく 1 つだけ。それなら RTO の満了(数百ミリ秒〜秒単位の沈黙)を待つのは無駄です。タイムアウト再送は沈黙からの推理、高速再転送は届いている証拠からの推理。障害ログでどちらの再送が起きているかで、ネットワークの状態の読みが変わります(第 5 章・第 7 章)。
この章で持ち帰ること
- 番号はバイトごと。seq = 1001 の 500 バイトはバイト 1001〜1500 を運ぶ
- ack 番号 = 次に欲しいバイトの番号。しかも累積確認 — 穴の先には進めない
- ロスへの気づき方は 2 つ。沈黙(RTO 満了、指数バックオフ)と悲鳴(重複 ACK 3 回 → 高速再転送)
- 重複 ACK 由来の再送は軽症、タイムアウト由来の再送は重症のサイン
ここまでで「必ず届く・順番どおり」の仕組みが揃いました。次章は約束その 3 の前半 — 相手の都合に合わせるスライディングウィンドウです。ACK に相乗りしてくる「あと何バイト受け取れるか」という数字が主役になります。