確認応答番号
TCPで、受信側が「次に受け取りたいデータのシーケンス番号」を送信側に知らせる番号。受け取ったシーケンス番号に、受け取ったデータのオクテット数を足した値になる。
イマシルちゃんの解説
宅配便で荷物を何個か受け取ったとき、
「1番から10番まで届いたよ」って言う代わりに、「次は11番をちょうだい」って返事をするのが確認応答番号なんだ。
「次は11番」って言えば、10番まではちゃんと届いたってわかるよね。
もし途中の荷物が届いてなかったら、何度でも「次は5番をちょうだい」って言い続けて、送り直してもらうんだよ!
より深い解説
定義
確認応答番号(Acknowledgment Number)は、TCPヘッダーにある32ビットのフィールドで、受信側が次に受信を期待するバイトのシーケンス番号を示す。コントロールフラグのACKが1のときに有効になる。
確認応答番号 = 受け取ったシーケンス番号 + 受け取ったデータのオクテット数
例:シーケンス番号3001、データ200バイトのセグメントを受け取った場合、確認応答番号は3201になる。
累積確認応答
TCPの確認応答は、「この番号より前のデータは、すべて受け取った」ことを意味する(累積確認応答)。
例:1001~1500、1501~2000、2001~2500の3つのセグメントのうち、2つ目が失われた場合
| 受け取ったセグメント | 返す確認応答番号 |
|---|---|
| 1001~1500 | 1501 |
| (1501~2000は届かない) | − |
| 2001~2500 | 1501(2つ目がまだなので、変わらない) |
途中が欠けている間、受信側は同じ確認応答番号を繰り返し返す(重複ACK)。送信側は、同じ確認応答番号を3回重ねて受け取る(重複ACKが3つ届く)と、タイマーの時間切れを待たずに、そのセグメントを再送する。これを高速再送(ファストリトランスミット)という。
SACK(選択的確認応答)
累積確認応答だけでは、欠けた部分より後ろに届いたデータがあることを送信側は知らない。SACK(Selective ACK)オプションを使うと、受信側は「2001~2500は届いている」と知らせることができ、送信側は欠けた部分だけを再送できる。
遅延ACK
受信側は、セグメントを受け取るたびにすぐACKを返すのではなく、少し(最大500ミリ秒、一般には40~200ミリ秒程度)待ってから、まとめてACKを返したり、返送するデータに相乗りさせたり(ピギーバック)する。これを遅延ACKといい、ACKだけのセグメントの数を減らせる。
シーケンス番号との関係
| シーケンス番号 | 確認応答番号 | |
|---|---|---|
| 意味 | 自分が送るデータの先頭の位置 | 相手から次に受け取りたいデータの位置 |
| 基準 | 自分のデータの流れ | 相手のデータの流れ |
| 増え方 | 自分が送ったデータの量だけ増える | 相手から受け取ったデータの量だけ増える |
TCPの通信は双方向で、それぞれの方向が独立した番号を持つ。そのため、1つのセグメントの中のシーケンス番号と確認応答番号は、別の流れの番号であり、どちらが大きいかで再送かどうかを判断することはできない。
よくある誤解
| 誤解 | 正しくは |
|---|---|
| 受け取ったシーケンス番号を、そのまま確認応答番号として返す | 受け取ったデータの量を足した、次の番号を返す |
| 番号はセグメントごとに1ずつ増える | データのオクテット数だけ増える |
| 確認応答番号がシーケンス番号より小さければ再送である | 両者は別の方向の番号なので、比べても意味がない |