TCPの制御(スリーウェイハンドシェイク)
スリーウェイハンドシェイクは、3ウェイ・ハンドシェイク、「three-way handshaking」とも表記されます。
TCPの接続において、オープン時に、スリーウェイハンドシェイクという手順で、接続を確立します。このハンドシェイクで初期シーケンス番号を交換し、2つのホストがそれぞれの初期シーケンス番号を同期させます。
TCPの通信では、シーケンス番号を交換することが重要になってきます。
送信するデータは、セグメントという転送単位に分割されます。また、IPによる通信では、送信したパケットが送信した順に相手に届くことが保障されません。パケットは、ばらばらに到着することもあるのです。
そこで、TCPでは、送信したセグメントを元通りのデータに復元できるように、シーケンス番号を使用するようにしています。
シーケンス番号は、送信するデータに対して、それぞれのバイト位置を指すようになっていて、その番号に基づいて整列することで元通りのデータに復元できるようにしています。
シーケンス番号
TCPヘッダは、次のように構成されています。

上の図から分るように、シーケンス番号は、32bit長です。符号なしの整数値で表現されます。
TCPでは、コネクションを開始すると、通信路にはそれぞれランダムなシーケンス番号が初期値として与えられるようになっています。
なぜランダムなのかというと、いつも決まった数値で始まったり、「1,2,3,4,5・・・」などと順番に割り当てられたとすると、セグメントの偽装が行い易いからです。そのため、スリーウェイハンドシェイクでは、コネクションの際にランダムに決めた値を初期値とするようになっています。
スリーウェイハンドシェイクの手順
TCPの通信において、オープン時に、スリーウェイハンドシェイクという手順で、接続を確立します。このハンドシェイクで、初期シーケンス番号を交換することで、2つのホストが、それぞれの初期シーケンス番号を同期させています。
同期は、SYN(同期制御ビット)と初期シーケンス番号で構成されるパケットを交換することで行われます。
その手順は、次のように行われます。
手順 | 内容 |
手順1 | 送信元が相手に対して、「SYNパケット」を送信する。 |
手順2 | SYN パケットを受け取った相手は、送信元に接続を許可する「SYN,ACKパケット」を送信する。 |
手順3 | SYN ACK パケットを受けとった送信元は、接続開始をあらわす ACK パケットを送信し、受信側との通信を開始する。 |
スリーウェイハンドシェイクの様子を図で表すと次のようになります。

上の図の流れは、以下のようになります。
1.送信側 → 受信側
送信側が、初期シーケンス番号が「x」であることを示すSYNパケットを受信側に送信します。
送信側から受信側に
「SYN,送信側のシーケンス番号=x」
が送信されます。
2.送信側 ← 受信側
受信側は、送信側のシーケンス番号が「x」であることを記録し、自分の初期シーケンス番号を「y」、ACK に「x+1」をセットしたパケットを送信側に送信します。
「ACK=x+1」にするのは、「x」までのオクテットを受信できており、その次に「x+1」が必要であることを意味しています。
受信側から送信側に
「SYN,受信側のシーケンス番号=y,ACK=x+1」
が送信されます。
3.送信側 → 受信側
送信元は、受信側のシーケンス番号が「y」であることを記録し、ACK に「y+1」をセットしたパケットを受信側に送信します。
「ACK=y+1」にするのは、「y」までのオクテットを受信できており、その次に「y+1」が必要であることを意味しています。
送信側から受信側に
「ACK=y+1」
が送信されます。
このように、スリーウェイハンドシェイクでは、3つのパケットを往復させることで、コネクションを確立します。
TCPでは、UDPと比べてかなり複雑な制御が行われていることが分かります。
もう少し分かり易いように、今度は、具体的に初期シーケンス番号が以下の値である場合のやり取りを示します。
送信元の初期シーケンス番号・・・1000
受信側の初期シーケンス番号・・・2000
