【図解】TCPコネクション〜3wayハンドシェイク→http→TCP FINのシーケンスを見る〜

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

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

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

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

TCPのデータ送信

TCPはデータを信頼性は、シーケンス番号と応答確認番号で実装されます。

データが欠けている場合、再送をしますが、再送タイマのタイムアウト時間(RTO: Retransmission TimeOut)はRTT値を元に計算されます。

RTT値は、データを送ってからackが戻ってくるまでの時間のことで、Windowサイズ毎に1パケットだけサンプリングされます。

さらにこのRTT値はSmooth RTT(SRTT)値の計算に用いられます。SRTT値の計算式は以下の通りです。

SRTT(new) = α * SRTT(old) + (1-α) * RTT

αは0.9が推奨されています。

また、RTOは以下の式が利用されています。

RTO = SRTT + 4 * (平均偏差)

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 を一緒にしてしまう実装もあります。このあたりはアプリケーションでどのように実装しているかに依存します。

最近では片方しか FIN を送らない実装もあるようです。(次のパケットキャプチャの例)

3way handshake をパケットキャプチャで見てみる

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 == 10281" でフィルタして表示しています。なので、1つのTCPコネクションのみが表示されています。

最初の3行が 3way Handshake です。そしてその後にクライアントからサーバに対して http 通信(GETメソッド)を発行しています。その次に ACK を挟んで http レスポンスコード200 OK が返されています。それに対しても ACK が返され、数秒経った後にサーバから [FIN, ACK] でコネクションを閉じています。(これ以降は tcp 10281 の通信は表示されませんでした。)

TCP/UDP の勉強については、以下の書籍がお薦めです。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする