🎉

TCPのコネクション確立(ESTABLISHED)とはどういう状態?

2025/03/05に公開

HTTP通信におけるTCPのコネクション確立というものが、具体的にどういう状態であるか知りたかったので、調べたことをまとめます。

コネクション確立、HTTP通信開始までの流れ

HTTP通信の開始は、まずTCPによる接続確立から始まります。これは「3ウェイハンドシェイク」と呼ばれる工程で行われ、以下の手順で進みます。

  1. SYN送信 : クライアントがサーバへ接続要求のSYNパケットを送信。
  2. SYN/ACK応答 : サーバがその要求を受け取り、SYNとACKの両方を含むパケットで応答。
  3. ACK送信 : クライアントがACKパケットを返送し、接続が確立される。

このハンドシェイクが完了すると、TCPは「ESTABLISHED」状態となり、HTTP通信を行う準備が整います。

クライアント                           サーバ
   |       --- SYN -------->           |
   |       <---- SYN/ACK ---           |
   |       --- ACK -------->           |
   |       接続確立(ESTABLISHED)       |

「コネクション確立(ESTABLISHED)」とはどういう状態なのか

TCPの3ウェイハンドシェイクが完了すると、TCBとソケットが作成されます。これらの準備が整うことをESTABLISHEDといいます。

Transmission Cntrol Block (TCB)
TCBとはOSカーネル内でTCP接続に関する情報を管理するためのデータ構造で、以下の情報を保持します。

  • 接続情報 : クライアントとサーバのIPアドレス、ポート番号
  • シーケンス番号と確認応答番号 : 送信および受信のデータの順序を管理するための番号
  • ウィンドウサイズ : フロー制御のために送受信できるデータ量の制限
  • タイマーやフラグ : 再送制御や接続維持に関わる各種タイマー、状態を示すフラグ

これら情報はメモリ上で保持され、TCPスタックがデータの正確な送受信、再送、順序制御などを行うための基盤となります。

ソケット
アプリケーションがネットワーク通信にアクセスするためのエンドポイントとして抽象化されたオブジェクト(インスタンス)です。

  • ソケットはTCBなどの内部データ構造へのインターフェースとなり、アプリケーションから送受信要求を行う窓口として機能する。
  • 一度生成されると、通信が終了(FINやRSTパケットの交換)するまでメモリ上で保持される。

HTTP通信の終了

  • アプリケーションレベルの終了
    1つのHTTPリクエスト/レスポンスの応答が完了すると、その特定のHTTP通信(トランザクション)は終了します。しかし、HTTP/1.1以降では、persistent connection(キープアライブ)がデフォルトで有効なので、同じTCP接続を使って次のリクエスト/レスポンスを続けて行えるようになっています。

  • TCP接続の切断
    最終的に、通信を完全に終了する場合は、サーバかクライアントどちらかの方でTCP接続を閉じるための手続き(FINパケットの送信など)が行われます。これにより、TCPレベルで接続が解放されます。

Keep-Aliveについて

Webサーバ等の設定でKeep-Aliveを設定できますが、これは、TCP接続が確立された後に、1回のリクエスト/レスポンスのやり取り(HTTPトランザクション)で接続を閉じるのではなく、同じTCP接続で複数のHTTPトランザクションを行うための仕組みです。

以下の動きをします。

  1. TCP接続確立
    3ウェイハンドシェイク後、TCBやソケットが生成され、接続はESTABLISHED状態になり、HTTPリクエストを送る
  2. HTTPリクエストに対するレスポンスでKeep-Aliveを受け取る
    サーバがレスポンスを返す際、Connection: keep-aliveヘッダを付与(HTTP/1.0の場合。HTTP/1.1ではデフォルトで有効。HTTP/2は後述)することで、その時のTCP接続を開いたままにすることをクライアントに伝える
  3. 接続の再利用
    Connection: keep-aliveを受け取ると、レスポンス受信後もクライアントはTCP接続(TCBやソケット)を削除することなく維持され、後続のHTTPリクエストで同じ接続を使用する。

HTTP/2について

HTTP/2では、HTTP/1.xで使われる「Connection: keep-alive」ヘッダーは基本的に存在せず、プロトコルレベルでTCP接続が維持されるよう管理されます。このヘッダーを付与しても、意味のない情報として扱われます。

参考

Discussion