【通信プロトコル】Wiresharkとncで分解するTCP/HTTPの流れ(localhost:8080)

Wiresharkとncで分解するTCP/HTTPの流れ(localhost:8080)

ネットワークエンジニアにとって、プロトコルの挙動を「目視」することは、トラブルシューティング能力を磨くための最短距離です。特にTCPの3ウェイ・ハンドシェイクや、HTTPのメッセージ構造は、概念として理解していても、実際のパケットレベルでどうやり取りされているかを即座に言語化できるエンジニアは意外と少ないものです。

本稿では、ローカル環境(localhost:8080)を舞台に、Netcat(nc)を用いてHTTPサーバを擬似的に立ち上げ、クライアントからのリクエストをWiresharkでキャプチャすることで、TCPとHTTPがどのように連携して通信を成立させているのかを徹底的に分解します。

環境の準備とキャプチャの基本設定

今回の検証には、以下のツールを使用します。
・nc (Netcat): 簡易的なTCPサーバ/クライアントとして使用。
・Wireshark: パケットキャプチャおよび解析に使用。
・ループバックインターフェース: ローカル通信を監視するために必要。

まず、Wiresharkを起動し、キャプチャ対象として「Loopback: lo0」(Windowsの場合はNpcap Loopback Adapter)を選択します。フィルタには「tcp.port == 8080」を設定し、余計なノイズを排除して目的のパケットのみを表示させます。

次に、ターミナルを開き、ncコマンドで8080ポートをリッスンさせます。

# 8080ポートで簡易サーバを起動
nc -l 8080

別ターミナルから、HTTPリクエストを送るために再度ncを使用します。

# 8080ポートへ接続
nc localhost 8080
# 接続後に以下の文字列を入力してEnterを2回押す
GET / HTTP/1.1
Host: localhost:8080

TCP 3ウェイ・ハンドシェイクの観測

パケットキャプチャを確認すると、データ送信の前に必ず「SYN」「SYN/ACK」「ACK」の3つのパケットが確認できるはずです。これがTCPの接続確立プロセスです。

1. SYN: クライアントがシーケンス番号(Seq=0)を付与して接続を要求。
2. SYN/ACK: サーバがそれを受け取り、自身のシーケンス番号(Seq=0)と確認応答(Ack=1)を返送。
3. ACK: クライアントが最終確認としてAck=1を送信。

Wiresharkの「Expert Information」を確認すると、このやり取りがミリ秒単位の遅延もなく完了していることがわかります。ローカル環境であるため、物理的な遅延が発生せず、OSのネットワークスタック内部で完結するためです。ここで重要なのは、このハンドシェイクが「信頼性のある通信路」を確保するための儀式であるという点です。HTTPはこの「確立されたパイプ」の上を流れる単なるデータペイロードに過ぎないことを理解してください。

HTTPリクエストの解剖

ハンドシェイク完了後、クライアントから送信した「GET / HTTP/1.1…」がTCPセグメントとして流れます。Wiresharkでこのパケットを選択し、「Follow TCP Stream」を実行すると、やり取りの全容がテキストとして表示されます。

ここで注目すべきは、HTTPのヘッダー構造です。
・リクエスト行: メソッド(GET)、パス(/)、プロトコルバージョン(HTTP/1.1)
・ヘッダーフィールド: Host: localhost:8080など、サーバ側が必要とするメタデータ
・空行: HTTPメッセージの終端を示す非常に重要な役割を持つ

ncで入力する際、最後に空行(改行を2回)を入れる必要があるのは、HTTP/1.1プロトコルが「空行=ヘッダーの終わり」と定義しているためです。この空行がなければ、サーバ側はクライアントがいつ入力を終えるのか判断できず、タイムアウトまで待機し続けることになります。

TCPセグメントの分割と再構成

もしHTTPリクエストが非常に巨大な場合(例えばPOSTメソッドで大きなJSONを送る場合)、TCPはMTU(最大転送単位)に基づいてデータを分割します。Wiresharkで見ると、一つのHTTPリクエストが複数のTCPセグメントに分かれて送信され、受信側で「TCP Reassembly」が行われている様子を観察できます。

HTTPはアプリケーション層のプロトコルであり、TCPがデータを断片化しようが、順序が入れ替わろうが、TCP層が全てを正しく並べ替えてからアプリケーションに渡してくれると信じています。この「役割分担」こそが、TCP/IPモデルの強固な設計思想です。

実務アドバイス:なぜWiresharkで見るべきか

実務の現場で「Webサイトが表示されない」「APIがタイムアウトする」といった事象に遭遇した際、アプリケーションのログだけを頼りにするのは危険です。アプリケーションログには「接続失敗」としか出ない場合でも、パケットレベルでは「TCPのSYNが再送されている(=サーバが応答していない)」のか、「SYN/ACKは帰っているが、その後のHTTPレスポンスがない(=サーバアプリケーションの処理遅延)」のか、原因を特定できるからです。

特に、以下のような場面でこの分解スキルは真価を発揮します。
1. ファイアウォールでのドロップ確認: SYNを投げても返答がない場合、経路上のフィルタリングを疑う。
2. Keep-Aliveの検証: 1つのTCPコネクションで複数のHTTPリクエストが流れているかを確認。
3. MTUサイズによるパケットドロップ: パケットサイズが大きい時だけ通信が切れる場合、Path MTU Discoveryの失敗を疑う。

まとめ

Wiresharkとncを用いた検証を通じて、TCPが通信の「土台」を作り、HTTPがその上で「意味のあるデータ」を運んでいるという関係性が明確になったはずです。

エンジニアとして成長するためには、ブラックボックスをそのまま受け入れるのではなく、今回のようにコマンドラインツールで環境を再現し、パケットレベルで何が起きているかを自分の目で確認する習慣が不可欠です。localhostでの実験は、ネットワークの基礎を学び直すための最も安全で、かつ最も教育的な環境です。ぜひ、ncの代わりにtelnetを使ってみたり、HTTPS(TLS)の場合にパケットがどう暗号化されるのか(鍵交換プロセスの観測)など、検証の幅を広げてみてください。

ネットワークの挙動を可視化できれば、どんな難解なトラブルも「パケットが語る真実」を読み解くことで、必ず解決の糸口が見えてきます。

コメント

タイトルとURLをコピーしました