【図解】TCPコネクションのシーケンスと状態確認〜3way handshake, FIN/RST, netstat〜

TCP コネクションの開始

TCP のコネクションは、3way ハンドシェイクにより始まります

3way ハンドシェイク時には、TCP のペイロードにはデータは一切入りません。この 3way ハンドシェイクが終わってから、TCP のペイロードに上位レイヤの情報 (例えば http) のデータやり取りが開始されます。

TCP コネクションを開始する (SYN を最初に送信する) ホストをクライアント、TCP コネクションを受ける (SYN を最初に受信する) ホストをサーバと言います。

以下に、TCP コネクションのサンプルを示します。

FIN による TCP コネクションの正常終了

TCP のコネクションは、ハーフクローズという方法で終了されます。つまり、片方ずつコネクションを切断します。

コネクションを切断したいほうは、FIN bit をセットして TCP セグメントを相手に贈ります。 最初に FIN を出す側を Active Close といいます。

一方、FIN を受け取った側は ACK bit とともに FIN bit をセットして TCP セグメントを送信します。 後に FIN を出す側を Passive Close といいます。

Active Close はどちらから行なっても良いことになっています。(アプリケーションでのソケットAPIの使い方次第です)。

なお、『FIN を受け取った側はまず ACK bit をセットした TCP セグメントを送り、一定待ち時間を待った後にFIN bitをセットした TCP セグメントを送る』という実装もありますが、上記のように ACK と FIN を一緒にしてしまう実装もあります。このあたりはアプリケーションでどのように実装しているかに依存します。

TCP Reset によるコネクションの強制終了

TCP RST を使うと一方的にコネクション終了を通知することができます。通信の途中、アプリケーションで不具合が発生した場合など、直ちに TCP RST を行い、通信を終了させます。

TCP RST がもしパケットロスした場合、相手には届きませんが、その場合は相手が TCP Open の前提で送信してきますが、そのたびに TCP RST を何度も送り続けることになります。

TCP RST の例は、次のパケットキャプチャで例を示します。

パケットキャプチャで見てみよう

Wireshark という無料ソフトでネットワークに流れるパケットを閲覧できます。

最近は https 通信が当たり前で、http 通信のできるサイトは少なくなってきました。このページも基本は全て https ですが、以下 URL だけは例外的に http 通信ができるようにしています。

http://milestone-of-se.nesuke.com/http.txt

上記 URL にアクセスしたときの通信をパケットキャプチャで見てみます。クライアント=192.168.100.100, サーバ=157.112.150.6 です。

取得したパケットキャプチャを "tcp.port == 11699" でフィルタして表示しています。なので、1つの TCP コネクションのみが表示されています。

最初の 3 行が 3way Handshake です。

そしてその後にクライアントからサーバに対して http 通信 (GETメソッド) を発行しています。その次に ACK を挟んで http レスポンスコード "200 OK" が返されています。

それに対しても ACK が返され、数秒経った後にサーバから [FIN, ACK] でサーバ⇒クライアント方向のコネクションを閉じています (Active Close)。そのまた数秒後にクライアントから [FIN, ACK] でクライアント ⇒ サーバ方向のコネクションを閉じています (Passive Close)。

実はこのキャプチャで使ったブラウザは IE11 なのですが、Passive Close についてはブラウザを閉じることで発生しました。Active Close が為される前にブラウザを閉じると、TCP Reset によるコネクションクローズが発生しました。

TCP コネクションの状態確認

Windows の場合はコマンドプロンプトで netstat -an を使うと状態が確認できます。

LISTENING が待ち受け(通信が来るのを待っている)状態で、ESTABLISHED は通信が来て処理を開始している状態です。その他の状態は以下を参照下さい。

【図解】TCPの状態遷移 〜Listen、Establish、FIN Wait等〜
【図解】TCPの状態遷移 〜Listen、Establish、FIN Wait等〜
TCP の State とは クライアントは TCP SYN を投げ、サーバは...

また、Linux のTCP/UDP状態確認については ss コマンドを使います。以下コマンドを参照下さい。

linux【ss/netstat】コマンドの見方/オプション~Recv-Q/Send-Qやポート確認(Listen/Estab/Unconn),プロセス表示等~
linux【ss/netstat】コマンドの見方/オプション~Recv-Q/Send-Qやポート確認(Listen/Estab/Unconn),プロセス表示等~
ss コマンド (旧 netstat コマンド) とは ss は socket...