Mímisbrunnr知恵の泉

← コンピュータネットワーク 一覧

🎓 レベル:標準 | 重要度:A(必須) 📎 前提:OSI参照モデルとTCP/IPモデル

要点(BLUF)

カプセル化の流れ(送信側)

ブラウザが GET / を送る場面を、上から下へ追います。

graph TD
  A["L7 データ(HTTPメッセージ)"]
  B["L4 セグメント(TCPヘッダ + データ)"]
  C["L3 パケット(IPヘッダ + セグメント)"]
  D["L2 フレーム(Ethernetヘッダ + パケット + FCS)"]
  E["L1 ビット列(電気・光・電波)"]
  A --> B --> C --> D --> E

各層が足すヘッダの中身を、役割つきで並べます。

付ける主な情報何のため
L4 TCP送信元/宛先ポート・シーケンス番号どのアプリへ・順序と再送のため
L3 IP送信元/宛先IPアドレス・TTL最終目的地まで経路選択するため
L2 Ethernet送信元/宛先MAC・タイプ・末尾にFCS次の1ホップへ届け、誤りを検出するため
L1(ヘッダなし)ビットを物理信号へ

ポイントは、下位層は上位層の中身を「ただのデータ(ペイロード)」として扱うことです。Ethernetフレームから見れば、IPパケットの中身が何であろうと関係なく、宛先MACへ運ぶだけです。

非カプセル化(受信側)

受信ノードは逆順にほどきます。各層は「自分宛てか」を確認してから上へ渡します。

  1. L1:信号をビット列へ復元
  2. L2:宛先MACが自分か確認 → FCSで誤り検査 → Ethernetヘッダを外す
  3. L3:宛先IPが自分か確認 → IPヘッダを外す
  4. L4:ポート番号から渡すアプリを決める → TCPヘッダを外す
  5. L7:アプリがHTTPメッセージを受け取る

機器ごとに「どこまで見るか」

途中の中継機器は、全層を開けるわけではありません。ここが実機の挙動を理解する鍵です。

graph LR
  PC1["送信PC(L1〜L7)"]
  SW["スイッチ(L2まで参照)"]
  RT["ルータ(L3まで参照)"]
  PC2["受信PC(L1〜L7)"]
  PC1 -->|"フレーム"| SW
  SW -->|"フレーム"| RT
  RT -->|"パケットを新フレームで"| PC2

このため、ping の宛先IPは固定でも、各区間の宛先MACは毎回変わります。これが「IPは最終目的地、MACは次の中継」の実体です。

計算/観察例:ヘッダのオーバーヘッドを数える

最小構成のヘッダサイズを Python で合算し、ペイロードに対する割り増しを確認します(言語明示)。

# 各層の代表的な最小ヘッダ長(バイト)
eth_header = 14   # Ethernet II ヘッダ(宛先6 + 送信元6 + タイプ2)
eth_fcs    = 4    # 末尾FCS
ip_header  = 20   # IPv4 最小
tcp_header = 20   # TCP 最小

payload = 100     # アプリデータ100バイトを送るとき
total = eth_header + ip_header + tcp_header + payload + eth_fcs
overhead = total - payload
print("payload bytes :", payload)
print("on-wire bytes :", total)
print("overhead bytes:", overhead)
print("overhead ratio:", round(overhead / total * 100, 1), "%")

実行結果:

payload bytes : 100
on-wire bytes : 158
overhead bytes: 58
overhead ratio: 36.7 %

100バイト送るのに58バイトの制御情報が乗ります。小さいデータを大量に送るほどヘッダ比率が上がるため、まとめて送る(バッファリング)ことが効率に効く、という直観につながります。

⚠️ よくある誤解

対応 lab

関連