仕組みから学ぶ Web
基礎読了目安 14#TCP#IP#パケット#ハンドシェイク

TCP/IP — データが相手に届くまでの4層

アプリが送った1行の文字列が、どう包まれて、どう運ばれ、どう元に戻るのか。障害の切り分けはこの層の把握から始まる。

この記事の進み方

What — データが包まれて運ばれる

アプリが GET /users と書いた瞬間から、相手のアプリがそれを読むまでに、データは4回包まれて4回開かれます。

Figure送信側:上の層から順に包んでいく
アプリケーション層+ HTTP ヘッダ何を伝えるかを決めるHTTP / gRPC / SMTP
トランスポート層+ TCP ヘッダどのアプリ宛かを決め、確実に届けるTCP / UDP
インターネット層+ IP ヘッダどの機械宛かを決めるIP / ICMP
リンク層+ Ethernet ヘッダ隣の機械に物理的に渡すEthernet / Wi-Fi
ネットワークケーブルを流れるバイト列
HTTP ヘッダデータ本体
1/4
アプリケーション層GET /users HTTP/1.1 のような、人間が読める意味のあるメッセージを作る。この層は相手がどこにいるかを知らない。

各層は自分のヘッダだけを付け、中身には触らない。だからアプリは IP アドレスを知らなくても通信でき、IP はそれが HTTP かどうかを知らずに運べる。

受信側はこれを逆順に開きます。リンク層のヘッダを剥がし、IP ヘッダを見て自分宛か確認し、TCP ヘッダのポート番号で渡す先のプロセスを決め、残った中身をアプリに渡す。

TCP は接続してから話し始める

IP は「投げるだけ」で、届いたかどうかを気にしません。TCP はその上に「確実に、順番どおりに」を載せます。そのために、通信の前に3回のやり取りで合意を取ります

Figure3ウェイハンドシェイクと切断
CLOSED両者

まだ何も始まっていない

SYN_SENTクライアント

接続要求を送って返事を待っている

SYN_RECEIVEDサーバー

要求を受け、こちらからも要求を返した

ESTABLISHED両者

データを送り合える状態

FIN_WAIT切断する側

こちらは送り終えたと伝えた

TIME_WAIT切断した側

遅れて届くパケットを待つ猶予時間

1/6
CLOSEDSYN 送信SYN_SENTクライアントが「話したい」と伝える。この SYN が捨てられると、応答なしでタイムアウトする。冒頭の事故はここ。

接続の確立に1往復半、切断に2往復かかる。この往復が「接続にかかる時間」の正体で、HTTP/2 や QUIC が減らそうとしているコストそのもの。

確認 — ここまで読めたか

サーバー上では curl localhost:3000 が 200 を返すのに、外からは接続できません。届いていないのはどこですか?

まず選ぶ(解答例は a〜d の記号で説明します)

Why — なぜ層に分けたのか

層に分けなければ、アプリケーションは「Wi-Fi で送る場合」「有線で送る場合」「衛星回線の場合」をそれぞれ知らなければなりません。逆に、新しい物理回線を作るたび、世界中のアプリを書き換える必要が出ます。

層の境界はそれぞれが知らなくてよいことを決めた線です。

  • HTTP は、相手が Wi-Fi か有線かを知らない
  • IP は、運んでいる中身が HTTP か動画かを知らない
  • Ethernet は、最終的な宛先がどこかを知らない(隣に渡すだけ)

この「知らなくてよい」が独立した進化を可能にしました。Wi-Fi が生まれても HTTP は無変更で動き、HTTP/2 が生まれても Ethernet は無変更で動きます。

なぜ TCP と UDP の2つがあるのか

IP の上に載せる選択肢が2つあるのは、確実さと速さが同時には成立しないからです。

CompareTCP と UDP の使い分け

順番と到達を保証する。1つ欠けたら、後続が揃っていても渡さずに待つ。

接続確立
1.5往復必要
欠損時
再送して待つ
順番
保証する
向いている用途
HTTP / DB / ファイル転送
  • 1バイトでも欠けると、その後ろのデータが揃っていてもアプリには渡さない。これが HOL ブロッキングの原因になる。
  • 混雑を検知すると自分から送信速度を落とす。ネットワーク全体が共倒れしないための仕組み。

TCP は「全部を、順番どおりに」を保証する代わりに待つ。UDP は待たない代わりに保証しない。どちらが優れているかではなく、失われたデータを再送する価値があるかどうかで決まる。

確認 — ここまで読めたか

TCP が UDP に対して提供しているものは何ですか?

まず選ぶ(解答例は a〜d の記号で説明します)

演習 — まず自分で判断する

解説を読む前に、まず自分で判断してみてください。ここで一度詰まっておくと、 次の節の判断軸が「なるほど」ではなく「そう来たか」に変わります。

演習 — 設計判断を問う

この症状から、どの層に原因があると切り分けますか?

与えられた条件
  • 社内の管理画面 admin.example.com が「たまに」開けないという報告が複数人から上がっている
  • 開けないときはブラウザに「応答時間が長すぎます」と出て、30秒ほどで失敗する
  • サーバー側のアプリケーションログには、失敗したはずのリクエストの記録が一切ない
  • サーバーの CPU・メモリは平常時と変わらない
  • 社内ネットワークからは失敗するが、モバイル回線からは常に成功する
この軸で考える
  • · アプリのログに記録がない、という事実が意味すること
  • · 「たまに」失敗するのか、「特定条件で必ず」失敗するのか
  • · 成功する経路と失敗する経路の差分はどこか
まず選ぶ(解答例は a〜d の記号で説明します)

演習 — 説明できるか

「API が落ちています」とだけ報告してきた後輩に、次に何を確認すべきかを説明してください

与えられた条件
  • 相手はアプリのログだけを見ている
  • 相手は層という概念を意識していない
  • 同じ報告の仕方を繰り返してほしくない

読み終わりましたか?

読了にすると、これを前提とする記事がロードマップで開放されます。

この記事を前提にしている記事