はじめに
こんにちは!SIerに入社して1年目の新人エンジニアです。日々の業務で当たり前のように使われている用語で「えっ、それって何?」と思ったものを調べて、自分なりにまとめていきます。
今回は「HTTP通信の流れ」について。
目次
TCP/IPモデルってそもそも何?
調べてみて最初に混乱したのが「OSI参照モデル」と「TCP/IPモデル」という似ているけど違う概念でした。今回はより実用的なTCP/IPモデルで説明します。
TCP/IPモデルは4つの層で構成されています
- ネットワークインターフェース層(物理層+データリンク層):物理的な接続と、LANなどの物理ネットワーク内での通信を担当
- インターネット層:異なるネットワーク間でのデータ配送を担当(IPがここで活躍)
- トランスポート層:端末間のデータ転送を制御(TCPやUDPがここに属する)
- アプリケーション層:ユーザーが使用するアプリケーションの通信を担当(HTTPはここ)
これらの層が連携して通信を実現しているんですね!
HTTP通信の基本的な流れ
HTTP通信は、クライアント(例えばブラウザ)からサーバーへのリクエストと、サーバーからクライアントへのレスポンスから成り立っています。
ざっくりとした流れはこんな感じ
- ユーザーがブラウザでURLを入力
- ブラウザがHTTPリクエストを作成
- リクエストデータが各層を通過して、徐々に必要な情報が追加される(カプセル化)
- ネットワークを通じてサーバーにデータが届く
- サーバー側で各層を逆に通過しながら、追加された情報が解析・除去される(脱カプセル化)
- サーバーアプリケーションがリクエストを処理
- レスポンスが同様のプロセスを逆に辿ってクライアントに戻る
カプセル化と脱カプセル化って何?
カプセル化:上位層から下位層へデータが渡される際に、各層で必要なヘッダー情報が追加されていく過程
脱カプセル化:下位層から上位層へデータが渡される際に、各層でヘッダー情報が解析・除去されていく過程
郵便物に例えると、最初に手紙(データ)を書いて、封筒に入れて(HTTPヘッダー)、宛先を書いて(TCPヘッダー)、郵便番号を追加して(IPヘッダー)、最後に配達方法の指示を書く(イーサネットヘッダー)みたいな感じです!
クライアント側のカプセル化
クライアントからサーバーへのHTTPリクエストが、各層でどのようにカプセル化されていくのか見ていきましょう。
アプリケーション層
ここでは、ユーザーがブラウザでWebページを表示しようとしている場面を想像してください。
- ユーザーが「https://example.com」と入力
- ブラウザがHTTPリクエストを作成します:
GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html,application/xhtml+xml,...
この時点でのデータ構造は
[HTTPヘッダー][HTTPデータ(空の場合もある)]
トランスポート層
アプリケーション層からデータを受け取ったトランスポート層(TCP)では:
- 宛先ポート(HTTPなら80番、HTTPSなら443番)と送信元ポートを決定
- データの分割(必要な場合)とシーケンス番号の割り当て
- TCPヘッダーを追加
TCPヘッダーには以下の情報が含まれます
- 送信元ポート番号(例: 51234)
- 宛先ポート番号(例: 443)
- シーケンス番号
- 確認応答番号
- コントロールフラグ(SYN, ACK, FIN など)
- ウィンドウサイズ
この時点でのデータ構造は
[TCPヘッダー][HTTPヘッダー][HTTPデータ]
インターネット層
トランスポート層からデータを受け取ったインターネット層(IP)では
- 送信元IPアドレスと宛先IPアドレスを決定
- 宛先IPはDNS解決で得られたexample.comのIPアドレス
- 送信元IPはクライアントのIPアドレス
- IPヘッダーを追加
IPヘッダーには以下の情報が含まれます
- プロトコルバージョン(IPv4/IPv6)
- 送信元IPアドレス
- 宛先IPアドレス
- データ長
- TTL(Time To Live)
この時点でのデータ構造は
[IPヘッダー][TCPヘッダー][HTTPヘッダー][HTTPデータ]
ネットワークインターフェース層
インターネット層からデータを受け取ったネットワークインターフェース層では
- MACアドレス(物理アドレス)の解決(ARP)
- 次のルーターのMACアドレスを取得
- イーサネットフレームのヘッダーとフッターを追加
イーサネットヘッダーには以下の情報が含まれます:
- 送信元MACアドレス
- 宛先MACアドレス
- イーサタイプ(例: IPv4, IPv6, ARP)
最終的なデータ構造は
[イーサネットヘッダー][IPヘッダー][TCPヘッダー][HTTPヘッダー][HTTPデータ][イーサネットフッター]
この形でデータはクライアントから物理的なネットワークを通ってルーターへ、そしてインターネットを経由して最終的にサーバーに届きます。
サーバー側の脱カプセル化
サーバーにデータが届くと、クライアント側と逆の流れで各層を上っていきます。
-
ネットワークインターフェース層:
- イーサネットヘッダーとフッターを確認・除去
- MACアドレスを確認(自分宛てか確認)
- IPパケットを抽出してインターネット層へ渡す
-
インターネット層:
- IPヘッダーを確認・除去
- IPアドレスを確認(自分宛てか確認)
- トランスポート層のデータを抽出して渡す
-
トランスポート層:
- TCPヘッダーを確認・除去
- ポート番号を確認(正しいサービス宛てか確認)
- データを結合(分割されていた場合)
- アプリケーション層にデータを渡す
-
アプリケーション層:
- HTTPヘッダーを解析
- リクエストを処理(Webサーバーが対応するリソースを探す)
- レスポンスを生成
HTTPレスポンスの流れ
レスポンスは基本的にリクエストと逆の流れをたどります:
- サーバーアプリケーションがHTTPレスポンスを作成
- アプリケーション層からトランスポート層へと下りながらカプセル化
- 物理的なネットワークを通じてクライアントへ
- クライアント側で脱カプセル化
- ブラウザがHTTPレスポンスを処理してWebページを表示
まとめ
HTTP通信は、一見シンプルな「リクエスト→レスポンス」の流れに見えますが、実際には複数のネットワーク層で様々な処理が行われていました。各層がそれぞれの役割を果たし、ヘッダー情報の追加(カプセル化)と解析・除去(脱カプセル化)を行うことで、インターネット上の異なるコンピュータ間での通信を実現しているようです。
参考資料