以下では、TCP 3ウェイハンドシェイクの各パケットにおける**フラグ(SYN/ACK)とシーケンス番号(Sequence Number)、確認応答番号(Acknowledgment Number)**がどのような値になるのかの典型例を示します。実際の値はOSによってランダムに初期化されますが(セキュリティ上、初期シーケンス番号は固定でなくランダムにする)、ここではわかりやすく「x」「y」という変数で表しています。
1. クライアント → サーバ: SYN パケット
-
フラグ:
- SYN = 1
- ACK = 0 (初回なのでACKフラグは立てない)
-
Sequence Number:
- Seq = x (クライアントが選んだ初期シーケンス番号。実際にはランダム)
-
Acknowledgment Number:
- Ack = 0 (初回なので意味を持たない)
この最初のパケットが「SYNフラグのみセットされている」状態です。
2. サーバ → クライアント: SYN+ACK パケット
-
フラグ:
- SYN = 1
- ACK = 1 (クライアントのSYNに対してACKする)
-
Sequence Number:
- Seq = y (サーバが選んだ初期シーケンス番号。実際にはランダム)
-
Acknowledgment Number:
- Ack = x + 1
- クライアントのSYNを受け取ったことを示すため、「相手のSeqに+1した値」をACK番号に入れる
このパケットでは、サーバも自分のSYNフラグをセット(SYN=1)し、同時に「クライアントのSYNを受け取りましたよ(ACK=1)」という情報を返します。
3. クライアント → サーバ: ACK パケット
-
フラグ:
- SYN = 0 (すでにSYNは完了しているので立てない)
- ACK = 1 (サーバのSYNを受け取ったことに対するACK)
-
Sequence Number:
- Seq = x + 1
- クライアント自身のシーケンスは、最初に使ったxに+1した位置(2番目の送信)から始まる
-
Acknowledgment Number:
- Ack = y + 1
- サーバのSYNに対して「受信したよ」と応答するため、サーバのSeqに+1した値
これでお互いのSYNを確認し合い、TCP接続(セッション)が確立します。
4. 全体のイメージ
- Client -> Server
- [ SYN=1, ACK=0, Seq=x, Ack=0 ]
- Server -> Client
- [ SYN=1, ACK=1, Seq=y, Ack=x+1 ]
- Client -> Server
- [ SYN=0, ACK=1, Seq=x+1, Ack=y+1 ]
- 1つめのパケット: クライアントがサーバへ「SYN=1, Seq=x」で送信
- 2つめのパケット: サーバが「SYN=1, ACK=1, Seq=y, Ack=x+1」で応答
- 3つめのパケット: クライアントが「ACK=1, Seq=x+1, Ack=y+1」で返す
これを「3ウェイハンドシェイク(3-way handshake)」と呼びます。ハンドシェイク後は、双方が x+1 と y+1 を基点にデータ(HTTPリクエストやレスポンス)を送受信していきます。
参考メモ
-
Initial Sequence Number (ISN)
- x や y は OS が適当な乱数を使うことが多い。古い実装では固定値や単純カウンタだったが、セキュリティ強化のため現在はランダム化されている。
-
SYN/ACK フラグは1ビット
- SYN=1 であれば「SYNフラグが立っている」、0 であれば「フラグなし」を意味する。
- ACK=1 であれば「ACKフラグが立っている」。
-
Ack = 相手のSeq + 1
- TCPでは「相手から送られてきたシーケンス番号に+1」を応答することで、相手のSYN(バイト数で1個分)を正しく受信したと知らせる仕組みをとっている。
-
3ウェイハンドシェイク完了後
- この接続上で実際のデータ通信(HTTPリクエスト/レスポンス)が始まる。
- HTTPS(TLS)の場合、TCP接続確立後にTLSハンドシェイクがさらに行われる。
まとめ
- SYNフラグは、接続開始を示す1ビットフラグ(SYN=1 → SYNパケット)。
- ACKフラグは、受信確認応答を示す1ビットフラグ(ACK=1 → ACKパケット)。
- 最初のパケットでは SYN=1, ACK=0、2番目では SYN=1, ACK=1、3番目では SYN=0, ACK=1 という値になるのが一般的な流れ。
- シーケンス番号 (Seq) は x や y のように乱数で初期化されるが、ACK番号 (Ack) は相手のSeqに+1をした値を設定する。
これが典型的な3ウェイハンドシェイク時の「SYN/ACKフラグ」と「シーケンス番号/ACK番号」のイメージです。