1.

TCP セグメント (PDU) 完全ガイド(MSS / MTU / Window)

編集
この記事の要点
  • セグメントは OSI 第 4 層 (Transport) の TCP の PDU (Protocol Data Unit) 名
  • 構造: TCP Header (20-60B) + Data、Header に Seq / Ack / Flags / Window / Checksum
  • MSS (Maximum Segment Size) = TCP データ部分の上限、Ethernet で 1460 バイトが標準
  • MTU (Maximum Transmission Unit) = IP パケット全体の上限 (Ethernet 1500B)、MSS = MTU - IP/TCP Header (40B)
  • IP Fragmentation と TCP セグメント化は別物。TCP は事前に MSS で切るので IP 分割は通常起きない

セグメントとは: TCP の PDU

OSI 参照モデルの各層では、運ぶデータの単位 (PDU = Protocol Data Unit) に決まった名前が付いています:

プロトコル例PDU 名
4. TransportTCPセグメント (Segment)
4. TransportUDPデータグラム (Datagram)
3. NetworkIPパケット (Packet)
2. Data LinkEthernetフレーム (Frame)
1. Physicalビット (Bit)

このページではこのうち TCP の セグメントを扱います。

TCP セグメントの構造

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Offset|Rsv|U|A|P|R|S|F|             Window Size                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options (0-40 bytes)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Data ...                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

最小 Header: 20 バイト (Options なし)
最大 Header: 60 バイト (Options 40B)

主要フィールドの意味

フィールドサイズ意味
Source / Destination Port各 16bit送受信ポート番号 (HTTP=80 等)
Sequence Number32bit送信バイトの通し番号
Acknowledgment Number32bit次に期待するバイト番号 (確認応答)
Data Offset4bitHeader 長 (4 バイト単位)
Flags (URG/ACK/PSH/RST/SYN/FIN)6bit制御フラグ
Window Size16bit受信可能バッファ残り (Flow Control)
Checksum16bit誤り検出
Options0-40BMSS, Window Scale, SACK, Timestamp 等

MSS と MTU

セグメントを語る上で外せないのが MSS と MTU の関係:

                   Ethernet Frame (1518 B)
+--------+----------+-------+--------+----------+-----+
| 14 B   |   20 B   | 20 B  |        Data        | 4 B|
| Eth Hd | IP Hdr   | TCP H |       (1460 B)     | FCS|
+--------+----------+-------+--------+----------+-----+
         |<----- MTU = 1500 ----->|
                   |<------ MSS = 1460 -------->|

MTU (Maximum Transmission Unit) = IP パケット全体の最大 = Ethernet で 1500
MSS (Maximum Segment Size)      = TCP のデータ部の最大  = MTU - 40 = 1460
媒体 / トンネル典型 MTU典型 MSS
Ethernet (一般)15001460
PPPoE (フレッツ等)14921452
IPv6 over IPv4 トンネル14801440
Jumbo Frame90008960
WireGuard / VPN1420 前後1380 前後
IPv6 最小12801220

MSS は 3-way handshake の SYN で双方が広告し合い、小さい方を採用します。

Path MTU Discovery (PMTUD)

エンド to エンドの経路上、最も MTU が小さい区間を Path MTU と呼びます。送信側がそれを上回るサイズを送るとパケットがどこかで捨てられるので、PMTUD で動的に発見します:

  1. 送信側は IP Header に DF (Don't Fragment) ビットを立てて送信
  2. 経路途中で MTU を超えるとルータが ICMP Type 3 Code 4 (Fragmentation Needed) を返す
  3. 送信側はその次の MTU まで縮めて再送

ICMP がブロックされている経路では PMTUD が機能せず、通信がブラックホール化します(「大きいファイルだけ転送失敗」「ssh は通るのに scp で固まる」等)。

TCP セグメント化と IP Fragmentation の違い

項目TCP セグメント化IP Fragmentation
誰が行う送信端末の TCP 層ルータ or 送信端末の IP 層
分割単位MSS (デフォルト 1460)MTU を超えた時に分割
順序保証TCP が再組立受信側 IP 層で再組立
性能正常運用★ 性能劣化 / ファイアウォール問題
UDP ではUDP では分割が起きやすい

TCP は事前に MSS で切ってから IP に渡すため、IP Fragmentation は基本起きません。起きている場合は MTU 設定ミスや MSS 広告漏れを疑います。

Wireshark でセグメントを見る

# キャプチャ → TCP セグメントをフィルタ
tcp.port == 80

# よく見るフラグ
SYN     : 接続開始
SYN+ACK : 接続受諾
ACK     : 確認応答
PSH+ACK : データ即時上層へ
FIN+ACK : 接続終了
RST     : 強制切断

# 役立つ表示
Stream Index            : セッション識別
Seq=, Ack=              : シーケンス番号
Win=, [TCP Window Full] : 受信バッファ枯渇
[TCP Retransmission]    : 再送
[TCP Dup ACK]           : 重複 ACK (Selective ACK のきっかけ)
[TCP Window Scale]      : 16bit を越える窓拡張

Nagle Algorithm

「小さいセグメントを大量に送ると非効率」なので、Nagle アルゴリズムが小さいデータを一旦バッファしてACK が返るまで待ってまとめて送信します。

  • 長所: 効率 UP
  • 短所: 対話型 (ssh / リアルタイムゲーム) では遅延感じる
  • 無効化: setsockopt(TCP_NODELAY, 1)

Window Scaling

TCP Window は 16bit (最大 64KB) ですが、現代の高速回線では小さすぎます。Window Scale オプションで SYN 時に倍率を交換し、最大 1GB までスケールできます:

# Linux で確認
cat /proc/sys/net/ipv4/tcp_window_scaling   # 1 なら有効

# Window サイズの自動チューニング
sysctl -a | grep tcp_rmem
# net.ipv4.tcp_rmem = 4096   131072  6291456

# BDP (Bandwidth Delay Product) で必要サイズ計算
# 例: 1Gbps * 100ms RTT = 12.5 MB

Selective ACK (SACK)

従来 TCP は「3 を受信し損ねた」とき 4, 5, 6 を受け取っていても全部再送になっていました。SACK では「3 だけ抜けてる」と報告でき、3 だけ再送で済みます。Linux / Windows ともデフォルト有効。

FAQ

Q: セグメント、データグラム、パケット、フレーム の違いは?
A: 階層別の PDU 名: TCP=セグメント、UDP=データグラム、IP=パケット、Ethernet=フレーム。実際には混用されますが、試験では区別必須。

Q: MTU を 9000 (Jumbo Frame) にすればいつでも速い?
A: 全経路の機器 (Switch / NIC / Router) が対応している必要があります。1 ヶ所でも 1500 だと PMTUD でブラックホール化する危険。社内 LAN 限定で使うのが現実的。

Q: PPPoE で MSS が小さくなる理由
A: PPPoE Header が 8 バイト分 IP 層に乗るため MTU が 1492 になり、MSS = 1452 に。フレッツ光ネクストでよく見ます。

Q: TCP セグメントと TLS レコードの関係
A: TLS は別レイヤ。TLS レコード (最大 16KB) が複数の TCP セグメントに分割されて運ばれます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. セグメント
  2. パケット
  3. フレーム

最近更新/作成されたページ