読み物 01. TCP/IP の歴史と仕組み - インターネットを成り立たせる原理

想定読了時間: 25-35分(移動中のスマホ読み想定) 読後に得られるもの: インターネットが「なぜ動いているのか」を物語として語れる。Wireshark のログや ssh のエラーが今までと違って見えてくる。 コードはほぼ無し: 概念・歴史・図解中心の読み物


はじめに: 「インターネットは誰のもの?」という問い

スマホで Google を開く。0.3秒で検索結果が返ってくる。当たり前すぎて誰も不思議に思わない。

でもここで一度立ち止まってほしい。

  • そのリクエストは、世界のどこを経由した?
  • なぜ Google のサーバーは「あなたのスマホ」を特定できる?
  • 経路の途中で電線が切れたらどうなる?
  • そもそも、この巨大な仕組みの「責任者」は誰?

答えを先に言うと、インターネットには中央管理者がいない。誰の所有物でもない。総務省でも国連でも Google でもない。それなのに動く。むしろ「誰のものでもないから動く」。

この奇跡を成り立たせている設計が TCP/IP という4文字です。今日はそれを物語として読みます。

この読み物のスタンス

教科書的に「TCP/IP とは…」と始めない。「人類が何に困って、何を発明したか」 という順で書く。技術の名前は道具の名前。道具は問題を解くために存在する。だから問題から入る。


第1章: 電話の時代 - 「線を独占する」という発想

1-1. 電話交換手のおばさん

20世紀前半、電話をかけるとどうなっていたか想像してほしい。

[あなた] ─── [電話局] ─── [相手]
              ↑
        交換手のおばさんが
        プラグを差し替える

電話局には壁一面のジャックボードがあり、交換手のおばさんがプラグを抜き差しして「あなた」と「相手」の間に物理的な銅線の道を作る。通話中はその線は2人専用。他の人は使えない。これを 回線交換 (Circuit Switching) という。

↓ 回線交換 vs パケット交換の比較 ↓

flowchart TB
    subgraph 回線交換
        A1[発信者] -->|専用線を確保| B1[交換局]
        B1 -->|通話中は占有| C1[受信者]
    end
    subgraph パケット交換
        A2[送信者] -->|パケット1| R1[ルーター]
        A2 -->|パケット2| R2[ルーター]
        A2 -->|パケット3| R3[ルーター]
        R1 -->|再組立| C2[受信者]
        R2 -->|再組立| C2
        R3 -->|再組立| C2
    end

回線交換の本質

「会話の始めから終わりまで、2点間に専用の通り道を確保する」 方式。

メリット: 一度繋がれば品質が安定する。会話の途中で「もしもし聞こえてる?」が起きにくい。

デメリット:

  • 線が物理的に必要なので、人数 × 距離分のケーブルが要る
  • 通話していない無音の時間も線を占有する(無駄)
  • 途中の交換局が1つ壊れたら通信が完全に死ぬ

使われている例: 固定電話(今でも一部)、ISDN、専用線サービス

1-2. 冷戦と「核戦争で死なないネットワーク」

1960年代、アメリカは冷戦の真っ只中だった。軍は本気でこう考えた。

「ソ連が核ミサイルを撃ってきて、ニューヨークの通信ハブが吹き飛んだら、ワシントンと西海岸の通信が途切れる。中央集権型の通信網は弱すぎる

ここから、「中央が無くても通信できる仕組み」 の研究が始まる。資金を出したのは米国国防総省の研究機関 ARPA(Advanced Research Projects Agency、現 DARPA)。

ARPA の凄み

ARPA は「インターネットを作ろう」と思って金を出したわけではない。「核戦争でも生き残る通信網」 を求めただけ。結果としてインターネットが生まれた。

同じ ARPA から生まれたものに GPS(軍事用衛星測位)や 音声認識の初期研究 がある。「軍が金を出して大学が好き勝手やった結果、世界が変わる」のパターン。


第2章: パケット交換という革命

2-1. 手紙を「ちぎって送る」発想

電話と違うアプローチを考えた人たちがいた。1960年代前半、ポール・バランやドナルド・デイヴィスといった研究者だ。彼らの発想はこうだった。

「メッセージを小さな『パケット』に分割して、それぞれを バラバラに ネットワークに流せばいい。途中の経路は気にしない。どこを通っても、最終的に宛先に着けば再組立できる」

例えるなら、長い手紙を破って何枚かの葉書にして、それぞれ別のルートで投函するイメージ。1枚目は東京経由、2枚目は大阪経由、3枚目は札幌経由でもいい。全部が着いたら順番通りに並べ直す

[送信側]                          [受信側]
"Hello World"
   ↓ 分割
┌─[H]─[e]─[l]─[l]─[o]─...
│
├─→ ルートA ─→ "H" "l" "W" "r" ─┐
├─→ ルートB ─→ "e" "o" "o" "l" ─┼─→ 再組立 → "Hello World"
└─→ ルートC ─→ "l"  " " "d"    ─┘

パケット交換 (Packet Switching) の本質

データを パケット という小さな単位に分割して、各パケットを 独立に 経路選択させながら送る方式。途中の経路は固定されない。

メリット:

  • 1つの線を多数の通信が同時に使える(多重化)
  • 一部の経路が壊れても、別の道を選んで届く(耐障害性)
  • 物理的な専用線が要らない

デメリット:

  • パケットが順番通りに着かない / 一部が消える可能性がある
  • 「順番直し」「欠落補修」を別途やる必要がある

この「別途やる必要がある」を担当するのが、後で出てくる TCP

2-2. ARPANET の誕生 (1969)

1969年10月29日、午後10時30分。カリフォルニア大学ロサンゼルス校 (UCLA) からスタンフォード大学のコンピュータに、史上初のパケットが送られた。

送ろうとした文字: LOGIN 実際に届いた文字: LO

… そう、3文字目でクラッシュした。これがインターネットの記念すべき最初の通信である。なんとも人間味のあるスタートだ。

ARPANET と「インターネット」は別物

ARPANET は最初は4ヶ所(UCLA、スタンフォード、UCSB、ユタ大)を繋いだだけのネットワーク。これがどんどん拡張されて、他のネットワーク(NSFNET、商用網など)とも相互接続 されて初めて「インターネット = ネットワークのネットワーク」になる。

「inter-net」の「inter」は「相互接続」の inter。これが本質。


第3章: TCP/IP の発明者たち

3-1. Vint Cerf と Bob Kahn

ARPANET は動いた。だが問題があった。「ARPANET 同士は話せるが、別ネットワーク(衛星網、無線網、有線網など)とは話せない」。それぞれが独自のプロトコルを使っていたから。

1973年、ARPA の研究者 Bob KahnVint Cerf(当時スタンフォード大の助教授)に相談を持ちかける。「異なるネットワーク同士を繋ぐ共通言語を作りたい」。

二人は紙とペンで設計を始め、翌1974年に論文 “A Protocol for Packet Network Intercommunication” を発表した。これが TCP/IP の原型 である。

Vint Cerf が「インターネットの父」と呼ばれる理由

厳密には「父」は複数いる(Bob Kahn、ポール・バラン、レナード・クラインロック等)。だが Vint Cerf は今も健在で、Google のチーフ・インターネット・エバンジェリストとして広報活動を続けている。だから象徴的存在として扱われる。

彼は現在も「IPv6 を使え、IPv4 はもう限界だ」と世界中で訴え続けている。後でこの話に戻る。

3-2. 設計思想: 「ネットワークはバカでいい」

TCP/IP の設計には、当時の常識を覆す思想があった。

従来の電話網:

  • 端末(電話機)はバカ(ダイヤルとマイクだけ)
  • ネットワーク(電話局)が賢い(経路選択、課金、エラー処理を全部やる)

TCP/IP:

  • 端末(コンピュータ)が賢い(エラー検出、再送、順序復元を全部やる)
  • ネットワーク(ルーター)はバカでいい(パケットを次の人に渡すだけ)

これを End-to-End 原則 と呼ぶ。インターネット設計の核心思想。

なぜ End-to-End 原則が革命的だったか

端末が賢いと、ネットワーク自体は単純にできる。単純なものは安く作れる、増やせる、壊れにくい、誰でも参入できる。

結果として何が起きたか:

  • ルーター業者は「パケット転送」だけ作れば商売になる(Cisco の隆盛)
  • 通信会社は「土管」を売るだけ(中身に関知しない)
  • 端末側で HTTP / SMTP / SSH / WebSocket / QUIC など好き放題なプロトコルが生まれた

もし「ネットワークが賢い」設計だったら、新しいアプリケーションを作るたびに通信会社に許可を取る必要があった。今のような爆発的な革新は起きていない


第4章: TCP/IP の4層モデル

ここからが技術的本論。安心してほしい、コードは出てこない。

4-1. 層 (Layer) という考え方

TCP/IP は「役割ごとに分けて積み重ねる」設計になっている。料理に例えるとこう:

┌───────────────────────────┐
│ お客さん(注文する人)       │ ← どんな料理を頼むか考える
├───────────────────────────┤
│ ウェイター(注文を伝える人) │ ← 注文を正確に厨房に届ける
├───────────────────────────┤
│ 料理人(作る人)             │ ← 厨房の中で料理する
├───────────────────────────┤
│ 食材配送(運ぶ人)           │ ← 食材を厨房まで運ぶ
└───────────────────────────┘

各層は「自分の上下の層」としか会話しない。お客さんは食材配送業者に直接話さない。これがレイヤー分けの嬉しいところ。

4-2. TCP/IP の4層

┌─────────────────────────────────────────────┐
│ 4. アプリケーション層                        │
│    HTTP / HTTPS / SSH / DNS / SMTP / FTP     │ ← アプリが直接使う言語
├─────────────────────────────────────────────┤
│ 3. トランスポート層                          │
│    TCP / UDP                                 │ ← 「届くこと」を保証する係
├─────────────────────────────────────────────┤
│ 2. インターネット層                          │
│    IP / ICMP                                 │ ← 「住所」と「経路」の係
├─────────────────────────────────────────────┤
│ 1. リンク層                                  │
│    Ethernet / Wi-Fi / 光ファイバー           │ ← 物理的に1ホップ運ぶ係
└─────────────────────────────────────────────┘

各層が何をしているか、料理の例で

  • アプリケーション層: お客さん。「ハンバーグ定食ください」(= 「GET /index.html ください」)
  • トランスポート層: ウェイター。「ハンバーグ、ライス、味噌汁、漬物の4品ですね」と分解して厨房に伝え、全部揃ったか確認する
  • インターネット層: 配膳ロボット。テーブル番号(IPアドレス)を見て正しいテーブルに運ぶ
  • リンク層: ロボットの車輪。床の上を1メートル動かす物理動作

4-3. データが層を降りていく様子

あなたがブラウザで https://google.com にアクセスすると、こうなる。

[アプリ層] "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
                                ↓ TCPヘッダを付ける
[トランスポート層] [TCP: 送信元ポート/宛先ポート/順序番号] + [HTTPデータ]
                                ↓ IPヘッダを付ける
[インターネット層] [IP: 送信元IP/宛先IP/TTL] + [TCP+HTTPデータ]
                                ↓ Ethernetヘッダを付ける
[リンク層] [Eth: 送信元MAC/宛先MAC] + [IP+TCP+HTTPデータ]
                                ↓ 電気信号 or 電波
[物理] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━>

各層は「自分のヘッダ」を前に付け足して下に渡す。受信側は逆順に剥がしていく。封筒に封筒に封筒を入れているイメージ。これを カプセル化 (Encapsulation) と呼ぶ。

Wireshark で見るとどう見えるか

パケット解析ツール Wireshark を立ち上げて1つのパケットをクリックすると、まさにこの構造が階層的に表示される:

Frame 1: 583 bytes on wire
  Ethernet II, Src: aa:bb:cc:..., Dst: 11:22:33:...
    Internet Protocol Version 4, Src: 192.168.1.10, Dst: 142.250.196.110
      Transmission Control Protocol, Src Port: 51234, Dst Port: 443
        Transport Layer Security
          Hypertext Transfer Protocol
            GET / HTTP/1.1

上から リンク層 → IP層 → TCP層 → アプリ層 という順。この読み物を読み終えたあと Wireshark を触ると、「あ、これ全部知ってる名前だ」となるはず。


第5章: OSI 7層モデルとの関係

教科書を開くと、TCP/IP の4層ではなく OSI 参照モデル の7層が載っている。なぜ2つあるのか。

5-1. OSI 7層モデル

┌──────────────────────┐
│ 7. アプリケーション層 │  ← ユーザー向けインターフェース
├──────────────────────┤
│ 6. プレゼンテーション層 │  ← 暗号化・圧縮・文字コード変換
├──────────────────────┤
│ 5. セッション層       │  ← 通信セッションの管理
├──────────────────────┤
│ 4. トランスポート層   │  ← データの到達保証
├──────────────────────┤
│ 3. ネットワーク層     │  ← ルーティング
├──────────────────────┤
│ 2. データリンク層     │  ← 隣接ノード間の通信
├──────────────────────┤
│ 1. 物理層             │  ← 電気信号・光・電波
└──────────────────────┘

OSI は 1984年に 国際標準化機構 (ISO) が「これが世界標準のネットワークモデルだ」と決めた。教科書はこっちで書かれている

5-2. でも現実は TCP/IP が勝った

ところが、OSI が「標準」と決まる頃には、ARPANET 由来の TCP/IP がすでに動いていて、しかも無料で誰でも使えた

結果は明白だった。実装が先にある TCP/IP が現場を制覇し、OSI は教科書の中の概念モデルとして残った。実際に IP パケットを送るプロトコルとしての OSI はほぼ存在しない。

標準化の皮肉

「これから標準を作る」と委員会で議論しているうちに、現場では「動くもの」が普及してデファクトになる。これは技術の世界で何度も起きるパターン。

  • OSI vs TCP/IP → TCP/IP の勝ち
  • Token Ring vs Ethernet → Ethernet の勝ち
  • ATM vs IP → IP の勝ち
  • VHS vs Betamax → VHS の勝ち(技術的優劣ではなく流通の話)

「動いて、安くて、誰でも使える」が勝つ。

5-3. 対応表

OSI 7層TCP/IP 4層代表例
7. アプリケーション4. アプリケーションHTTP, SSH, DNS
6. プレゼンテーション4. アプリケーションTLS(暗号化)
5. セッション4. アプリケーション(TLS の一部、Cookie)
4. トランスポート3. トランスポートTCP, UDP
3. ネットワーク2. インターネットIP
2. データリンク1. リンクEthernet, Wi-Fi
1. 物理1. リンク銅線, 光ファイバー

実務では「L4 ロードバランサ」「L7 ルーティング」のように OSI の番号で呼ばれることが多い。「L4 = トランスポート = TCP/UDP の情報で振り分け」「L7 = アプリ = HTTP の URL を見て振り分け」という意味。

↓ OSI 7層 と TCP/IP 4層 の対応関係 ↓

flowchart LR
    subgraph OSI[OSI 7層モデル]
        O7[7. アプリケーション層]
        O6[6. プレゼンテーション層]
        O5[5. セッション層]
        O4[4. トランスポート層]
        O3[3. ネットワーク層]
        O2[2. データリンク層]
        O1[1. 物理層]
    end
    subgraph TCPIP[TCP/IP 4層モデル]
        T4[4. アプリケーション層<br/>HTTP/SSH/DNS/TLS]
        T3[3. トランスポート層<br/>TCP/UDP]
        T2[2. インターネット層<br/>IP/ICMP]
        T1[1. リンク層<br/>Ethernet/Wi-Fi]
    end
    O7 --> T4
    O6 --> T4
    O5 --> T4
    O4 --> T3
    O3 --> T2
    O2 --> T1
    O1 --> T1

実務で「Layer 4」「Layer 7」と聞いたら

  • L4 ロードバランサ: TCP の接続レベルで振り分ける(高速、中身は見ない)。AWS の NLB (Network Load Balancer) がこれ
  • L7 ロードバランサ: HTTP の URL やヘッダを見て振り分ける(柔軟、中身を見る)。AWS の ALB (Application Load Balancer) がこれ

/api/* は API サーバーへ、/static/* は CDN へ、みたいな振り分けは L7 でしかできない。


第6章: IP アドレス - インターネット上の住所

6-1. IPv4: 32ビットの住所

IP アドレスとは、ネットワーク上の機器1台1台に割り当てられた住所192.168.1.10 のような4つの数字で書く。これを IPv4 と呼ぶ。

192.168.1.10
 │   │   │  │
 │   │   │  └─ 0-255 の数字
 │   │   └──── 0-255 の数字
 │   └──────── 0-255 の数字
 └──────────── 0-255 の数字

各数字は 0〜255 まで(= 8ビット = 2の8乗)。4つあるので合計 32ビット。表現できる住所の総数は…

2^32 = 4,294,967,296 個 (約43億)

1970年代、Vint Cerf たちが TCP/IP を設計した時、彼らはこう考えた。

「世界に43億個のアドレスがあれば永遠に足りるだろう」

これが致命的な見誤りだった。

6-2. IPv4 はなぜ枯渇したか

1980年代、Vint Cerf は「地球上のすべての人にコンピュータが割り当てられる時代が来るとは思わなかった」と振り返っている。

実際には、人類は IP アドレスを以下の用途で猛烈に消費した:

  • 1990年代: パソコン1人1台時代
  • 2000年代: 携帯電話、ノートPC、サーバー
  • 2010年代: スマホ、IoT、ルーター、テレビ、冷蔵庫…

2011年、IANA (Internet Assigned Numbers Authority) という IPアドレスを管理する組織のプールがゼロになった。地域ごとの管理組織(アジアは APNIC)も次々に枯渇した。日本の組織 JPNIC が「もう新規 IPv4 アドレスは出せません」と宣言した。

6-3. IPv6: 128ビットの住所

枯渇を見越して 1990年代に設計されたのが IPv6。アドレスは 128ビット

2001:0db8:85a3:0000:0000:8a2e:0370:7334

表現できる総数:

2^128 = 340,282,366,920,938,463,463,374,607,431,768,211,456
       ≈ 3.4 × 10^38 個

これは地球上の砂粒1粒1粒に何兆個ずつ割り当ててもまだ余るレベル。「もう枯渇しない」を本気で目指した数。

IPv6 の桁数の比喩

よく使われる比喩: 「地球の表面 1平方ミリメートルあたり 6.7 × 10²³ 個のアドレスが割り当てられる」

1平方ミリ = 米粒の数百分の一。そこに地球から太陽までの星の数くらいのアドレスを置ける。人類はもう一生、IPv6 アドレスを使い切れない

6-4. なのに IPv6 が普及しない理由

設計思想は理想的。アドレスは無限。なのに 2026年現在も、まだ世界の通信の半分以上は IPv4 で動いている。

なぜか? 答えは1つ。

NAT があったから IPv4 で凌げてしまった

次の章で NAT を解説する。

「次世代規格が普及しない問題」の典型例

IPv6 は「次の世代の標準」と1998年に決まった。が、2026年でも完全移行は終わっていない。

同じパターン:

  • HTTP/2 → 2015年勧告、普及まで5年以上
  • HTTP/3 (QUIC) → 2022年標準化、普及途上
  • Python 2 → Python 3 → 13年以上かかった

「動いてるものは置き換えられない」のがインフラの宿命


第7章: NAT - 家庭の Wi-Fi が動く秘密

7-1. 家の中の「偽 IP アドレス」

あなたの家のスマホやPCには、こんな IP アドレスが振られているはず。

192.168.1.10   (スマホ)
192.168.1.11   (ノートPC)
192.168.1.12   (プリンタ)

これらは プライベートIPアドレス。「家庭内専用」「組織内専用」と決められたアドレス帯で、世界中で重複している。あなたの家の 192.168.1.10 も、隣の家の 192.168.1.10 も、ニューヨークのオフィスの 192.168.1.10 も、全部別物。

プライベートIP アドレス帯(RFC 1918 で定義)

  • 10.0.0.010.255.255.255 (大企業向け、1677万個)
  • 172.16.0.0172.31.255.255 (中規模、約100万個)
  • 192.168.0.0192.168.255.255 (家庭・小規模、6.5万個)

あなたの家のルーターを開いて IP 設定を見ると、99% この中のどれかが使われている。

7-2. 外に出るときどうする?

「世界中で重複しているアドレス」のままでは、インターネットに出られない。外の世界には世界で唯一の住所 (グローバルIP) を持つ必要がある。

ここで活躍するのが NAT (Network Address Translation)、日本語で「ネットワークアドレス変換」。

[家の中]                      [ルーター]                  [インターネット]
192.168.1.10  ─────┐                                      
                    │
                    ↓
              [NAT テーブル]
              内側 ← → 外側
              192.168.1.10:54321 ⇔ 203.0.113.5:62000  ← 1つのグローバルIP
              192.168.1.11:54322 ⇔ 203.0.113.5:62001     を全員でシェア
              192.168.1.12:54323 ⇔ 203.0.113.5:62002
                    │
                    └─────────────────────→ Google

NAT の本質

家の中の住所 (プライベートIP) を、外の世界の住所 (グローバルIP) に翻訳する」仕組み。

やってること:

  1. 家のスマホがインターネットに出る時、ルーターが「お前のリクエスト、俺のグローバルIPで代理送信しとくな」とパケットを書き換える
  2. 戻ってきたパケットを「これはスマホ宛だな」と判別して、家の中のスマホへ転送する
  3. 家の中に10台あろうが、外から見ると 1個のグローバルIP に見える

嬉しい点:

  • 家庭1軒に必要なグローバルIPは1個で済む。IPv4 枯渇の延命になった
  • 家の中の機器が外から直接見えない → セキュリティの副次的なメリット

辛い点:

  • 「家の中の特定の機器に外からアクセスする」が難しい (ポートフォワーディングの設定が要る)
  • 機器同士が直接 P2P で繋ぐのが難しい (Skype や WebRTC は STUN/TURN サーバーで穴を開ける)

↓ 家庭ルーターでの NAT 変換の流れ ↓

flowchart LR
    subgraph 家の中[家の中 プライベートIP]
        S[スマホ<br/>192.168.1.10:54321]
        P[PC<br/>192.168.1.11:54322]
        T[TV<br/>192.168.1.12:54323]
    end
    subgraph ルーター
        N[NATテーブル<br/>内側ポート ⇔ 外側ポート]
    end
    subgraph インターネット[インターネット グローバルIP]
        G[Google<br/>142.250.196.110:443]
    end
    S -->|送信元書き換え| N
    P -->|送信元書き換え| N
    T -->|送信元書き換え| N
    N -->|203.0.113.5:62000| G
    G -->|応答| N
    N -->|どの機器宛か判別| S

7-3. NAT のおかげで IPv4 が延命された

本来、地球上の機器全部にユニークな IPv4 アドレスを振ろうとすると 43億では足りない。だが NAT のおかげで、家庭・企業ごとに1個のグローバルIPで済むようになった。

結果として、「IPv6 に移行しなくても、しばらくは IPv4 で凌げる」 状態が続いた。これが Vint Cerf が嘆く「IPv6 が普及しない最大の理由」。

設計者たちのジレンマ

NAT は元々「IPv6 までの繋ぎ」として作られた緊急策。だが緊急策が想像以上に上手く動いてしまい、本格移行へのモチベーションを奪ってしまった。

Vint Cerf 本人は「NAT は End-to-End 原則を壊した」と何度も批判している。彼の原理主義から見ると、NAT は妥協の産物。だが世界はとっくに妥協の産物の上で動いている。


第8章: TCP - 「届く」を保証する係

8-1. TCP が解く問題

IP は「パケットを宛先に運ぼうとする」だけ。途中で消えるかもしれない、順番が入れ替わるかもしれない、重複するかもしれない。それを上の層で補修するのが TCP (Transmission Control Protocol)

TCP は以下を保証する:

保証する内容どうやって?
届いたこと受信側が「届いたよ」と返事 (ACK) を返す
届かなかったら再送一定時間 ACK が来なければ再送
順番を直す各パケットに番号を振り、受信側で並べ替え
重複を弾く同じ番号のパケットは1つだけ採用
流量制御受信側が「もうゆっくり送って」と申告できる

これだけ全部やるから、アプリ側は「HTTP リクエストを送ったら、ちゃんと届く」と信じてコードを書ける。素晴らしい仕事。

8-2. 3ウェイハンドシェイク

TCP は通信を始める前に「握手」をする。これが有名な 3ウェイハンドシェイク

[クライアント]                              [サーバー]
      │                                          │
      │ ── SYN ─────────────────────────────────→│
      │      「やあ、通信したい (番号: 1000)」    │
      │                                          │
      │←────────────────────── SYN-ACK ──────────│
      │   「了解、受けるよ (番号: 5000)         │
      │    あんたの1000受信した、1001頼む」      │
      │                                          │
      │ ── ACK ─────────────────────────────────→│
      │   「あんたの5000受信した、5001頼む」     │
      │                                          │
      │ ===== 接続確立、データ送受信開始 ======= │

何をしているか:

  1. SYN (Synchronize): クライアントから「会話始めたい」と申告。初期シーケンス番号 (例: 1000) を送る
  2. SYN-ACK: サーバーが「了解」(ACK) と「私もシーケンス番号 (例: 5000) 使うよ」(SYN) を同時返信
  3. ACK: クライアントが「OK、了解した」と最終確認

3往復で 互いに「相手が話を聞ける状態だ」と確認しあう。これで本番データの送信が始まる。

↓ 3ウェイハンドシェイクのシーケンス図 ↓

sequenceDiagram
    participant C as クライアント
    participant S as サーバー
    Note over C,S: 接続確立フェーズ
    C->>S: SYN (seq=1000)
    Note right of C: 通信したい
    S->>C: SYN-ACK (seq=5000, ack=1001)
    Note left of S: 了解、私のseqは5000
    C->>S: ACK (ack=5001)
    Note right of C: OK、確認した
    Note over C,S: 接続確立、データ送受信開始

なぜ「3回」なのか

直感的には「お互いがOK」と言えば良いから2回で十分そう。だがそれだとダメ。

例: クライアントが「会話したい」と送る → サーバー「OK」と返事 → これだけだと、サーバーから見て「自分のOKがクライアントに届いたか分からない」。クライアントが受け取れなかったら、サーバーは無駄に待ち続ける。

3回目の ACK が「サーバーから見て、自分のOKが届いた確認」になる。これで初めて両者が「相手が話を聞いている」と確信できる。

8-3. 終わるときは4回握手

接続を切るときは 4ウェイハンドシェイク (4回握手)。

[クライアント]                              [サーバー]
      │ ── FIN ─────────────────────────────────→│
      │      「もう送るもの無いです」              │
      │                                          │
      │←────────────────────── ACK ──────────────│
      │      「了解、こっちはまだ送るかも」       │
      │                                          │
      │      (サーバー側は残りデータを送信中)   │
      │                                          │
      │←────────────────────── FIN ──────────────│
      │      「こっちももう送るもの無いです」     │
      │                                          │
      │ ── ACK ─────────────────────────────────→│
      │      「了解、お疲れ様」                   │

なぜ4回かというと、TCP は双方向通信だから。「自分が話し終わった」のと「相手が話し終わった」を別々に宣言する。電話で「もう切るね」「うん、私も切るね、じゃあね」「うん、じゃあね」みたいな感じ。

↓ TCP データ送受信の全体フロー(接続確立から切断まで) ↓

sequenceDiagram
    participant C as クライアント
    participant S as サーバー
    Note over C,S: 1. 接続確立 (3-way)
    C->>S: SYN
    S->>C: SYN-ACK
    C->>S: ACK
    Note over C,S: 2. データ送受信
    C->>S: Data (seq=1, 100bytes)
    S->>C: ACK (ack=101)
    C->>S: Data (seq=101, 200bytes)
    S->>C: ACK (ack=301)
    S->>C: Response Data
    C->>S: ACK
    Note over C,S: 3. 接続終了 (4-way)
    C->>S: FIN
    S->>C: ACK
    S->>C: FIN
    C->>S: ACK

開発でよく見る CLOSE_WAIT TIME_WAIT の正体

サーバーで netstat を打つと CLOSE_WAITTIME_WAIT が大量に表示されることがある。

  • CLOSE_WAIT: 「相手から FIN が来たけど、自分の FIN をまだ送ってない状態」。アプリが close() を呼び忘れているとここで溜まる。バグの兆候
  • TIME_WAIT: 「正常に閉じた後、念のため待っている状態」。通常2分くらいで消える。大量にあるのは異常ではない

本番サーバーで CLOSE_WAIT が溜まり続けたら、コネクションリークを疑う。


第9章: UDP - 「速いけど雑」な兄弟

9-1. TCP がやらないことを全部やらない

TCP の対極が UDP (User Datagram Protocol)。これは:

  • 届いた確認: しない
  • 再送: しない
  • 順番直し: しない
  • 流量制御: しない

送りっぱなし。届くかどうかは知らん」というプロトコル。

9-2. なぜそんなものが存在する?

理由は 速さ。TCP の3ウェイハンドシェイクや ACK 待ちは、1パケット送るのに数十ミリ秒のロスを生む。リアルタイム性が命の用途では致命的。

用途TCP/UDP どっち?理由
Web (HTTP/1.1, HTTP/2)TCP1文字でも欠けると壊れる
メール (SMTP)TCP一文字も欠けてはいけない
ファイル転送 (FTP, SCP)TCP完全性が必要
音声通話 (VoIP, Zoom)UDP1パケット遅れるくらいなら欠けた方がマシ
動画ストリーミングUDP同上
オンラインゲームUDP過去のパケットより最新の状態が大事
DNS (名前解決)UDP (基本)1パケットで終わるから握手の時間が無駄
QUIC / HTTP/3UDP後述、UDPの上に独自の信頼性を再実装

UDP の哲学

信頼性は要らない、または上のレイヤーで自分で実装する」場面で UDP を選ぶ。

音声通話で TCP を使うと、1パケット遅れた時に「届くまで待つ」のが致命的。「うーんあーー(0.5秒遅れ)」みたいな会話になる。UDP なら「(欠落) 」と無音で済ませて、次のパケットですぐ復帰できる。会話としてはこっちの方が遥かにマシ。

9-3. QUIC = UDP の上に「賢いTCP」を再実装したもの

最近の HTTP/3 は QUIC という新しいプロトコルを使う。QUIC は UDP の上に動く。TCP は使わない。

なぜか? TCP は OS のカーネルに深く組み込まれていて、機能改善するのに「OSアップデートが必要」になる。それでは進化が遅い。

そこで Google が「UDP は『何もしない』プロトコルだから、その上に賢い再送・順序制御を自前で実装すれば、TCP より柔軟に進化できる」と考えた。これが QUIC。

QUIC = TCP の現代版

  • 接続確立が速い (TCPの3ウェイ + TLSの握手 を1往復にまとめた)
  • パケットロスに強い (1ストリームの遅延が他に波及しない)
  • 接続情報が「IPアドレス」じゃなく「コネクションID」(Wi-Fi → 4G に切り替えても接続が切れない)

「TCP の良いところを取って、悪いところを修正した」のが QUIC。UDP は単なる土台として再活用された

↓ TCP と QUIC のスタック比較 ↓

flowchart TB
    subgraph 従来[従来のHTTPS HTTP/2まで]
        H1[HTTP/1.1 or HTTP/2]
        T1[TLS 1.2/1.3]
        TCP1[TCP<br/>信頼性・順序保証・輻輳制御]
        IP1[IP]
        H1 --> T1 --> TCP1 --> IP1
    end
    subgraph 新しい[HTTP/3]
        H3[HTTP/3]
        Q[QUIC<br/>TLS 1.3内蔵<br/>信頼性・順序保証・ストリーム独立]
        U[UDP<br/>シンプルな配送のみ]
        IP2[IP]
        H3 --> Q --> U --> IP2
    end

第10章: ポート番号 - サーバーの中の「窓口」

10-1. ポート番号とは

IP アドレスはサーバーの住所。じゃあ「サーバー上のどのアプリと話したいか」はどう指定する?

答え: ポート番号。0〜65535 の数字で、IP アドレスと組み合わせて使う。

http://93.184.216.34:80/
                    ↑
                  ポート番号

サーバー側で「ポート80番を見張ってる Apache」「ポート22番を見張ってる sshd」と複数のアプリが同時に動ける。クライアントはポート番号で「どの窓口に話したいか」を指定する。

ポート番号の3区分

  • 0-1023: Well-known ports (有名な番号、サーバー用に予約)
  • 1024-49151: Registered ports (登録された番号、特定アプリ用)
  • 49152-65535: Dynamic / Ephemeral ports (クライアント側が一時的に使う)

10-2. 覚えておくべき well-known ports

ポートプロトコル何のサービス?
22TCPSSH (リモートログイン)
25TCPSMTP (メール送信)
53UDP/TCPDNS (名前解決)
80TCPHTTP
110TCPPOP3 (メール受信、旧)
143TCPIMAP (メール受信、新)
443TCPHTTPS
3306TCPMySQL
5432TCPPostgreSQL
6379TCPRedis
27017TCPMongoDB
8080TCPHTTP 代替 (開発用)

これ全部覚えなくていい。だが 22, 80, 443, 3306, 5432, 6379 は実務で頻出。バックエンドエンジニアなら反射的に出てきてほしい。

lsof -i -P -n で見えるもの

Mac のターミナルで lsof -i -P -n を打つと、今このマシンで動いている「ポートを開いているプロセス」が一覧表示される:

COMMAND     PID   USER   TYPE NODE NAME
node      12345  takato  IPv4 TCP  127.0.0.1:3000 (LISTEN)
Postgres  23456  takato  IPv4 TCP  127.0.0.1:5432 (LISTEN)
Code      34567  takato  IPv4 TCP  127.0.0.1:6463 (LISTEN)

「node が 3000 番で待ち受け中」と読める。npm run dev で動かしてるアプリだ。自分のマシンで何が動いているかを可視化するのに便利。

10-3. ポート番号と TCP/UDP の組み合わせ

ポート番号は TCP と UDP で別物

  • TCP 80番UDP 80番 は別のポート
  • HTTP は TCP 80、DNS は基本 UDP 53

ファイアウォール設定で「80番開ける」と言ったら必ず TCP/UDP どっちかを指定する。

ssh が繋がらないエラーの典型原因

ssh user@serverConnection refusedConnection timed out が出る場合、原因のほとんどはこれ:

  1. 22番ポートが開いてない (sshd が起動してない or ファイアウォールで弾かれている)
  2. IPアドレスを間違えている (DNS で別のサーバーに繋がっている)
  3. NAT/ルーターでポートフォワーディングがない (家庭内サーバーに外から繋ぐとき)

エラーメッセージで切り分け:

  • Connection refused → ポートには到達してる、でも誰も応答してない (sshd 落ちてる?)
  • Connection timed out → ポートにすら到達してない (ファイアウォール? IP違い?)
  • Permission denied → 接続はOK、でも認証で弾かれた (鍵 or パスワード違い)

この読み物を読むと エラーメッセージが意味を持って読めるようになる。


第11章: なぜ中央管理者がいないのに動くのか

11-1. ルーティングの「自己組織化」

世界中のルーターはお互いに「俺の隣にはこのネットワークがあるよ」と情報を交換し合っている。これを ルーティングプロトコル と呼ぶ。代表が BGP (Border Gateway Protocol)

[ISP-A]──[ISP-B]──[ISP-C]
   │       │       │
   ├──"私の先には 8.8.0.0/16 がある"
   │       ├──"私の先には 203.0.113.0/24 がある"
   │       │       └──"私の先には 198.51.100.0/24 がある"
   │       │
   各ルーターが「経路の地図」を自動的に組み立てる

各ルーターは隣のルーターから情報を受け取り、自分の経路表 (ルーティングテーブル) を作る。「Google の IP に向けたパケットは、隣の ISP-B に渡せばOK」みたいな表。誰も全体を管理していない。各ルーターは隣の話だけ聞いて、結果として世界全体が繋がる。

自己組織化の凄み

インターネットには中央管理者がいない、と最初に書いた。本当にいない。

  • どのルーターも、世界全体の地図を知らない
  • でも隣の経路情報を交換するだけで、結果的に世界中に届く

これは蟻の巣やニューロンの集合に近い性質。個々はバカでも、全体としては賢い。

中央集権でないからこそ、1ヶ所が壊れても全体は動き続ける。これが Vint Cerf たちが設計した冷戦時代の理念そのまま。

↓ クライアントからサーバーまでの経路(インターネットの構造) ↓

flowchart LR
    C[クライアント<br/>スマホ/PC] --> H[家庭ルーター<br/>NAT]
    H --> ISP1[ISP-A<br/>地域プロバイダ]
    ISP1 --> BB[バックボーン<br/>BGP経由のISP間接続]
    BB --> IX[インターネット<br/>エクスチェンジ]
    IX --> ISP2[ISP-B<br/>サーバー側プロバイダ]
    ISP2 --> DC[データセンター<br/>ロードバランサ]
    DC --> S[サーバー]

11-2. でも完全に「無管理」ではない

「中央管理者がいない」は正確には語弊がある。最低限の役割を担う組織はある。

  • IANA / ICANN: IPアドレス・ドメイン名の世界的な管理 (重複しないよう調整)
  • IETF: プロトコル仕様の標準化 (RFC文書を発行する)
  • 地域 RIR (APNIC, ARIN, RIPE NCC etc): 地域ごとの IP 割り当て
  • JPNIC, JPRS: 日本のドメイン (.jp) 管理

これらは「ルールを決める」「重複を避ける」のが仕事。「通信そのもの」には介入しない。

「ガバナンスの薄さ」がインターネットの本質

各国政府は「インターネットを管理したい」と思っている (中国のグレートファイアウォール、ロシアの SORM など)。だが TCP/IP の設計上、完全な管理は不可能になっている。

なぜなら:

  • ルーターは隣の情報だけで動く (中央サーバーを止めても止まらない)
  • 暗号化通信 (TLS) は中身が見えない
  • VPN や Tor のような迂回ルートが容易に作れる

「設計思想がそのまま政治的な性質を生んでいる」 数少ない例。


章の問い (考えるための小さなトリガー)

読みながら / 読み終わって考えてほしいこと

  1. もし TCP/IP に「中央管理者」がいたら、今のインターネットはどう変わっていただろうか? 動画配信、SNS、Web は同じように発展しただろうか?
  2. あなたが普段使っているサービス (LINE, YouTube, Slack…) は、TCP と UDP のどちらで動いていると予想する? なぜそう思う?
  3. IPv6 が普及しない最大の理由が NAT だとして、本気で IPv6 に移行させるには、何をどうすればいい?

答えを暗記する必要はない。「自分なりに考える筋肉」を動かすのが目的。


第12章: まとめと、ここから何ができるか

12-1. 今日の物語

ここまでの話を一言でまとめると:

1960年代の冷戦期、「核戦争でも生き残る通信」を求めた研究から、「中央管理者のいないパケット交換」というアイデアが生まれた。それを実装した TCP/IP が世界のデファクトとなり、End-to-End 原則のおかげで End 側 (アプリ側) で爆発的なイノベーションが起きた。43億のアドレスは足りなくなったが、NAT が延命し、まだ IPv6 への完全移行は終わっていない。

12-2. これを知っていると何が読めるようになるか

  • Wireshark のパケットダンプが「Ethernet → IP → TCP → HTTP」の階層として読める
  • ssh: connect to host xxx port 22: Connection refused というエラーが「ポート22にTCP接続を試みたが応答がなかった」と分かる
  • AWS の VPC 設計 で「10.0.0.0/16」と書かれたサブネット指定の意味が分かる
  • netstat -anlsof -i の出力 (LISTEN, ESTABLISHED, TIME_WAIT…) が読める
  • L4 ロードバランサと L7 ロードバランサ、どっち使う?」の設計判断ができる
  • ping (ICMP), traceroute (UDP/ICMP), nslookup (DNS over UDP) が「どの層で動いているか」分かる
  • DDoS 攻撃の「SYN flood」「UDP flood」がなぜ効くか分かる

12-3. 次に深掘るなら

公式の一次資料

  • RFC 791: IP の仕様 (1981年。短い、読める)
  • RFC 793: TCP の仕様 (1981年。これも読める)
  • RFC 9000: QUIC の仕様 (2021年。長いが現代の集大成)
  • RFC 8200: IPv6 の仕様 (1998年改訂、2017年再改訂)

RFC は「インターネットの聖書」。バックエンドエンジニアなら一度は RFC 793 を斜め読みする価値がある。1981年の文書が今の世界を動かしている事実だけで感動する。

書籍

  • TCP/IP Illustrated, Vol.1』(W. Richard Stevens) - 古典の最高峰。図解で理解できる
  • マスタリングTCP/IP 入門編』(オーム社) - 日本語の定番、初学者向け
  • 詳解 TCP/IP』 - もっと深く

動かして学ぶ

  • Wireshark をインストールして、自分のブラウザ通信をキャプチャしてみる (アンインストール後の解析も可能)
  • tcpdump -i en0 host google.com でターミナルからパケット観察
  • traceroute google.com で「世界中のルーターを何ホップ経由しているか」を見る
  • オンラインゲーム中netstat を打って「UDPで通信してる」を確認する

締めの一言

インターネットは、誰の所有物でもない。誰も全体を理解していない。なのに毎日数十億人を運ぶ。

これを作ったのは、冷戦期に紙とペンで設計を考えた数人の研究者と、その理念を信じて実装した無数のエンジニアたち。End-to-End 原則 という思想だけが、今もすべてのインフラの根底に流れ続けている。

次にスマホで Google を開くとき、ぜひ少しだけ想像してほしい。あなたのパケットは、太平洋を渡る海底ケーブルを通り、知らない国の知らないルーターを5つも6つも経由して Google のデータセンターに辿り着いている。誰の許可も得ず、誰の管理も受けず、ただ TCP/IP という共通言語だけを頼りに。

それが、Vint Cerf たちが半世紀前に夢見た世界です。


次に読むなら

3 までの30年

TCP/IP の上で動く最大のプロトコル、HTTP の歴史を辿る読み物。なぜ HTTP/2 はバイナリになったのか、なぜ HTTP/3 は TCP を捨てて UDP に乗り換えたのか。今日読んだ TCP の弱点が、そのまま HTTP/3 の設計動機になっている話。