1ー1 TCPによる通信方法
「TCP」は、IPパケットを正しく転送するために用いられるトランスポート層のプロトコル。TCPは、コネクションレス型プロトコルの「IP」を使用して、コネクション型の通信を行い、高信頼の通信を実現する。
「TCP」では、
◆コネクション管理
◆パケットの順序制御
◆エラー検出と訂正
◆フロー制御
を行っている。
■コネクション
「TCP」は、コネクション型プロトコルで、データを送信する前に通信相手とのコネクション(論理的な通信路)を確立する。一度、コネクションを確立すると、TCP/IP通信における様々な規約を考慮しなくても、転送が可能になる。

1-2 スリーウェイハンドシェイク
「TCP」は、データを送信する前に「スリーウェイハンドシェイク」というプロセスを利用して通信相手とのコネクションを確立する。

「スリーウェイハンドシェイク」では、「SYN」と「ACK」の2つのフラグを使用し、TCPセグメントを交換する。また、このときに実際のデータ転送に使用するための「シーケンス番号」と「確認応答番号」を決定する。
シーケンス番号は送るデータの先頭バイト番号。確認応答番号は次に送って欲しいデータの先頭バイト番号になる。
以下の図で、「TCPスリーウェイハンドシェイク」の手順を示す。


【スリーウェイハンドシェイク手順】
【1】:接続開始側(ホストA)が、相手のポート番号と自分のポート番号を指定し、自らTCPソケットの確立を開始する「アクティブオープン(自分から先に接続要求を相手に送信すること)」を行う。接続の開始は、「SYNフラグ」に1を立て、TCPセグメントを送信する。「シーケンス番号」にはランダムな値が設定(ここでは1000)され、確認応答番号は「0」。
【TCP状態:CLOSED→SYN_SENT】《接続開始側》
【2】:応答側は、接続側が要求したポートを開けて接続待ちになっている場合に、コネクションを作成する「パッシブオープン(接続を受け付けること)」を行う。この時、フラグの「SYN」と「ACK」の両方に「1」が立てられている。
初回の応答であることを表すために、「接続開始側が送信したシーケンス番号に1を足した値」を確認応答番号としてセットする。また、シーケンス番号には、ランダムな値(ここでは2000)が設定される。また、接続開始時には、通信するデータの最大値を決める。この最大値(TCP通信において1つのセグメントで運ぶことができるデータ量)を「MSS」といい、送信側、受信側でそれぞれ値を指定し、どちらか小さい方を採用する。
【TCP状態:LISTEN→SYN_RCVD】《応答側》
【3】:最後に、このパッシブオープンの接続を確認するにあたって、接続開始側がセグメントを返す。このとき、フラグ「ACK」に「1」が立てられる。また、シーケンス番号には「応答側の確認応答番号」をそのまま利用する。
また、受け取ったシーケンス番号を確認する意味で、応答側から送られたシーケンス番号に「1」を足した値を確認応答番号にセットする。そして、フラグ「ACK」に「1」が立てられる。
【TCP状態:SYN_SENT→ESTABLISHED】《接続開始側》
【TCP状態:SYN_RCVD→ESTABLISHED】《応答側》
以上で、TCPコネクションの確立が完了した。この後、実際のデータ転送が開始される。データ転送時に使用するシーケンス番号は、スリーウェイハンドシェイクの値がそのまま使用される。
【TCPコネクション確立後のデータ転送】
TCPコネクション確立後の手順は以下の通り。


【4】:送信元は「500」バイトのデータを送信するとする。この時フラグの「ACK」に「1」が立てられる。また、シーケンス番号と確認応答番号には、スリーウェイハンドシェイク直後と同じ値が設定されている。
【5】:送信先は「1500」バイトのデータを送信するとする。この時、フラグの「ACK」に「1」が立てられる。また、シーケンス番号には【4】の確認応答番号「2001」が設定され、確認応答番号には【4】のシーケンス番号に受信したデータサイズを加算した「1501」が設定される。
【6】と【7】も上記と同様の考え方になる。
【TCPコネクション切断時】
全てのデータを送信し終わると、TCPコネクションを切断する。正常終了の場合は、終了の開始側と応答側で「FIN/ACK」、「ACK」、「FIN/ACK」、「ACK」のセグメント交換が行われる。この手順を以下に示す。


【8】:終了開始側(ホストB)はデータの送信が完了したので、コネクションの切断要求を送信する。終了開始側(ホストB)がFIN(終了)フラグをオンにし、それまでのデータを正常に受信したことを知らせるため、「ACK」フラグをオンにし、「FIN/ACKセグメント」を送信する。
また、シーケンス番号は、【7】のシーケンス番号に送信したデータサイズを足した値「5001」(3501+1500)が設定され、確認応答番号には、【7】の確認応答番号と同じ値が使用される。
【TCP状態:ESTABLISHED→FIN_WAIT-1】《終了開始側》
【TCP状態:ESTABLISHED→CLOSE_WAIT】《応答側》
【9】:応答側(ホストA)は、もし送っていないデータがあれば、それらを全て送信する。全てのデータを送っている場合は、接続開始側のシーケンス番号に「1」を足した値を確認応答番号にセットする。
終了開始側(ホストB)からの切断要求(FIN)を受信したので、応答側(ホストA)は切断要求に対する確認応答を送信する。この確認応答番号を有効にするために、「ACK」フラグを有効にして、終了手続きに入る。この時、終了開始側(ホストA)から、【8】で受けとった確認応答番号をシーケンス番号とする。また、確認応答番号は、【8】のシーケンス番号に「1」を加算した値になる。
【TCP状態:FIN_WAIT-1→FIN_WAIT-2】《終了開始側》
【10】:応答側(ホストA)からもコネクションの切断要求を送信する。それまでのデータを正常に受信できたことを示すため、「ACK」フラグをオンにし、確認応答番号をセットするとともに、接続の終了を行うため、「FIN」フラグを付けてセグメントを返す。つまり、「FIN」と「ACK」両方のフラグが立てられている。
【TCP状態:CLOSE_WAIT→LAST_ACK】《応答側》
【11】最後に終了開始側(ホストB)が、応答側(ホストA)のセグメントを受け取り、それまでのシーケンス番号と、応答側(ホストA)のシーケンス番号に「1」を加算した値を確認応答番号にセットする。そして確認応答番号を有効にするため、「ACK」フラグをオンにしたセグメントを送り、接続を終了する。
【TCP状態:FIN_WAIT-2→TIME_WAIT】《終了開始側》
【TCP状態:LAST_ACK→CLOSED】《応答側》
なお、終了開始側(ホストB)の「TIME_WAIT」は、「最大セグメント有効時間(MSL)」※の2倍の時間にタイムアウトするように規定されている(推奨値は240秒)。
※「MSL最大セグメント有効時間(MSL)」とはTCPセグメントがインターネット上に存在し得る最長時間。
以上の様に、TCP接続切断時には「4回会話」することで、TCPコネクションを正常に終了する。