確認応答番号
TCPで、途切れずに受信できたデータの続きとして次に受け取りたいデータのシーケンス番号を送信側へ知らせる番号。この番号より前のデータはすべて受信済みであることを表す。
イマシルちゃんの解説
TCPでは、送るデータの位置を1バイトずつシーケンス番号で区別するんだ。
確認応答番号は、受信側が次に受け取りたいデータの位置を送信側に伝える番号だよ。
例えば1001番から1100番まで途切れずに届いたら、1101を返すんだ。
途中が欠けていたら、後ろのデータが届いても欠けた先頭の番号を知らせるよ。
このように、それより前はすべて受信済みだとまとめて伝えるのが累積確認応答なんだ。
送信側はこの返事を使って、届いた範囲を確かめたり再送が必要か判断したりできるんだよ。
この解説はわかりやすかったですか?
より深い解説
定義
確認応答番号(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ずつ増える | データのオクテット数だけ増える |
| 確認応答番号がシーケンス番号より小さければ再送である | 両者は別の方向の番号なので、比べても意味がない |