インターネット上でデータをやり取りする際、アプリケーション間の通信を担うのがトランスポート層です。このトランスポート層には、TCP(Transmission Control Protocol)とUDP(User Datagram Protocol)という2つの主要なプロトコルがあります。
TCPとUDPはどちらもIP上で動作しますが、信頼性と速度のトレードオフにおいて対照的な特徴を持ちます。この違いを正しく理解することは、適切な通信プロトコルを選択し、アプリケーションのパフォーマンスを最適化する上で非常に重要です。
本記事では、TCPとUDPの違いについて以下の内容を解説します。
- TCPの信頼性を実現する仕組み(3ウェイハンドシェイク、再送制御、フロー制御、輻輳制御)
- UDPの軽量でシンプルな通信モデル
- TCPヘッダとUDPヘッダの構造比較
- それぞれのプロトコルが適したユースケース
- 実際のネットワークコマンドでの確認方法
この記事を読むことで、TCPとUDPの特性を理解し、用途に応じたプロトコル選択ができるようになります。
前提条件
本記事を理解するために、以下の知識があることを前提としています。
- OSI参照モデルの第4層(トランスポート層)の役割を把握している
- IPアドレスとパケット通信の基本概念を理解している
- ポート番号の役割について基礎的な知識がある
実行環境
ネットワーク通信の確認には以下の環境を使用します。
| OS | 確認コマンド |
|---|---|
| Windows 10/11 | netstat -an、Test-NetConnection |
| macOS | netstat -an、nc(netcat) |
| Linux | ss -tuln、nc(netcat) |
特別なソフトウェアのインストールは不要です。
期待される学習成果
本記事を読み終えると、以下のことができるようになります。
- TCPとUDPの根本的な違いを説明できる
- TCPの3ウェイハンドシェイクの流れを図解できる
- 再送制御、フロー制御、輻輳制御の役割を理解できる
- アプリケーションの要件に応じてTCPかUDPを適切に選択できる
- ネットワークコマンドでTCP/UDP通信の状態を確認できる
トランスポート層の役割
OSI参照モデルにおいて、トランスポート層(第4層)はアプリケーション間の通信を担当します。ネットワーク層(第3層)がホスト間のパケット転送を担うのに対し、トランスポート層は以下の役割を果たします。
- エンドツーエンドの通信: 送信元アプリケーションから宛先アプリケーションへのデータ配送
- 多重化と分離: ポート番号を使用して、同一ホスト上の複数アプリケーションを識別
- データの整合性: チェックサムによるエラー検出
以下の図は、ネットワーク層とトランスポート層の関係を示しています。
flowchart TB
subgraph "送信側ホスト"
A1[アプリケーションA<br/>ポート80]
A2[アプリケーションB<br/>ポート443]
T1[トランスポート層<br/>TCP/UDP]
N1[ネットワーク層<br/>IP]
end
subgraph "受信側ホスト"
A3[アプリケーションA<br/>ポート80]
A4[アプリケーションB<br/>ポート443]
T2[トランスポート層<br/>TCP/UDP]
N2[ネットワーク層<br/>IP]
end
A1 & A2 --> T1
T1 --> N1
N1 -.->|パケット転送| N2
N2 --> T2
T2 --> A3 & A4ネットワーク層のIPはベストエフォート型のプロトコルであり、パケットの到達保証やデータの順序保証を行いません。これらの機能を必要に応じて提供するのがトランスポート層の役割であり、TCPとUDPは異なるアプローチでこの課題に対処します。
TCPの特徴と信頼性機能
TCP(Transmission Control Protocol)は、RFC 9293で規定されているコネクション型のプロトコルです。「信頼性のある、順序付けられたバイトストリームサービス」をアプリケーションに提供します。
TCPの主な特徴
TCPは以下の特徴を持つプロトコルです。
| 特徴 | 説明 |
|---|---|
| コネクション型 | 通信前に接続を確立し、終了時に切断する |
| 信頼性保証 | パケットロスを検出し、再送により確実に配送する |
| 順序保証 | シーケンス番号により、データを送信順に再構成する |
| フロー制御 | 受信側の処理能力に合わせて送信速度を調整する |
| 輻輳制御 | ネットワークの混雑状況に応じて送信レートを制御する |
これらの機能により、TCPは信頼性が必要なアプリケーション通信に広く使用されています。
TCPヘッダの構造
TCPセグメントのヘッダは最小20バイトで、以下の情報を含みます。
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 送信元ポート | 宛先ポート |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| シーケンス番号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 確認応答番号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|データ | |C|E|U|A|P|R|S|F| |
|オフセット| 予約 |W|C|R|C|S|S|Y|I| ウィンドウサイズ |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| チェックサム | 緊急ポインタ |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| オプション(可変長) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
各フィールドの役割は以下の通りです。
| フィールド | サイズ | 役割 |
|---|---|---|
| 送信元ポート | 16ビット | 送信側アプリケーションを識別 |
| 宛先ポート | 16ビット | 受信側アプリケーションを識別 |
| シーケンス番号 | 32ビット | このセグメントの最初のデータバイトの番号 |
| 確認応答番号 | 32ビット | 次に受信を期待するバイトの番号 |
| 制御フラグ | 各1ビット | SYN、ACK、FIN、RSTなどの制御情報 |
| ウィンドウサイズ | 16ビット | 受信可能なデータ量を通知 |
| チェックサム | 16ビット | データの整合性検証 |
3ウェイハンドシェイク
TCPでは通信開始前に、3ウェイハンドシェイク(3-Way Handshake)と呼ばれる手順でコネクションを確立します。この手順により、両端が通信の準備ができていることを相互に確認します。
sequenceDiagram
participant C as クライアント
participant S as サーバー
Note over C: CLOSED
Note over S: LISTEN
C->>S: SYN (seq=x)
Note over C: SYN-SENT
Note over S: SYN-RECEIVED
S->>C: SYN+ACK (seq=y, ack=x+1)
Note over C: ESTABLISHED
C->>S: ACK (seq=x+1, ack=y+1)
Note over S: ESTABLISHED
Note over C,S: データ通信開始各ステップの詳細は以下の通りです。
- SYN(同期): クライアントが接続要求を送信し、初期シーケンス番号(ISN)を提示
- SYN+ACK: サーバーが接続を承認し、自身の初期シーケンス番号を返送
- ACK(確認応答): クライアントが最終確認を送信し、コネクション確立が完了
この3段階の手順が必要な理由は、シーケンス番号がグローバルなクロックに基づいていないためです。古い重複したSYNセグメントと新しい接続要求を区別するために、相互確認のプロセスが必要です。
再送制御(Retransmission)
TCPはパケットロスを検出し、自動的に再送を行うことで信頼性を保証します。
sequenceDiagram
participant C as 送信側
participant S as 受信側
C->>S: セグメント1 (seq=100)
S->>C: ACK (ack=200)
C-xS: セグメント2 (seq=200) 損失
Note over C: タイムアウト発生
C->>S: セグメント2 再送 (seq=200)
S->>C: ACK (ack=300)
Note over C,S: 通信継続再送制御の主な仕組みは以下の通りです。
- タイムアウトベースの再送: 一定時間内にACKが返らない場合に再送
- RTO(Retransmission Timeout)の動的計算: ネットワーク状況に応じてタイムアウト値を調整
- 高速再送: 重複ACKを3回受信した場合、タイムアウトを待たずに再送
RFC 6298で規定されているRTOの計算では、RTT(Round Trip Time)のサンプルを測定し、平滑化された推定値を維持します。
フロー制御(Flow Control)
フロー制御は、受信側の処理能力を超えてデータが送られることを防ぐ仕組みです。TCPはスライディングウィンドウ方式を採用しています。
flowchart LR
subgraph "送信側バッファ"
direction LR
A1[送信済<br/>ACK待ち]
A2[送信可能<br/>ウィンドウ内]
A3[送信待ち<br/>ウィンドウ外]
end
subgraph "受信側バッファ"
direction LR
B1[受信済<br/>処理待ち]
B2[受信可能<br/>空き領域]
end
A2 -->|データ送信| B2
B1 -->|ウィンドウサイズ通知| A2受信側は、自身のバッファの空き容量をウィンドウサイズとしてTCPヘッダに含めて通知します。送信側はこのウィンドウサイズを超えてデータを送信しません。
ウィンドウがゼロになった場合(ゼロウィンドウ状態)、送信側は定期的にプローブセグメントを送信して、ウィンドウの再開を確認します。
輻輳制御(Congestion Control)
輻輳制御は、ネットワークの混雑を検出し、送信レートを調整してネットワーク全体のパフォーマンスを維持する仕組みです。
RFC 5681で規定されている基本的な輻輳制御アルゴリズムは以下の通りです。
| アルゴリズム | 動作 |
|---|---|
| スロースタート | 接続開始時に輻輳ウィンドウを指数的に増加 |
| 輻輳回避 | 閾値到達後に線形的に増加 |
| 高速再送 | 3重複ACKでパケットロスを検出 |
| 高速回復 | 高速再送後に輻輳ウィンドウを半減して再開 |
flowchart TB
subgraph "輻輳制御の状態遷移"
A[スロースタート] -->|cwnd >= ssthresh| B[輻輳回避]
A -->|3重複ACK| C[高速再送/回復]
B -->|3重複ACK| C
A -->|タイムアウト| A
B -->|タイムアウト| A
C -->|回復完了| B
end輻輳ウィンドウ(cwnd)は送信側が管理する仮想的なウィンドウであり、実際に送信できるデータ量はmin(cwnd, rwnd)(rwndは受信側のウィンドウサイズ)となります。
コネクション終了(4ウェイハンドシェイク)
TCPコネクションの終了は、4ウェイハンドシェイクで行われます。
sequenceDiagram
participant C as クライアント
participant S as サーバー
Note over C: ESTABLISHED
Note over S: ESTABLISHED
C->>S: FIN (seq=u)
Note over C: FIN-WAIT-1
S->>C: ACK (ack=u+1)
Note over C: FIN-WAIT-2
Note over S: CLOSE-WAIT
S->>C: FIN (seq=v)
Note over S: LAST-ACK
C->>S: ACK (ack=v+1)
Note over C: TIME-WAIT
Note over S: CLOSED
Note over C: 2MSL待機後
Note over C: CLOSEDTIME-WAIT状態は2MSL(Maximum Segment Lifetime、通常4分)間維持されます。これにより、遅延した古いセグメントがネットワークから消えるのを待ち、新しい接続との混同を防ぎます。
UDPの特徴とシンプルな通信モデル
UDP(User Datagram Protocol)は、RFC 768で規定されているコネクションレス型のプロトコルです。最小限のオーバーヘッドで高速な通信を実現します。
UDPの主な特徴
UDPはTCPと対照的な特徴を持ちます。
| 特徴 | 説明 |
|---|---|
| コネクションレス型 | 事前の接続確立なしにデータを送信 |
| 信頼性なし | パケットロスの検出や再送を行わない |
| 順序保証なし | パケットの到着順序を保証しない |
| 軽量 | ヘッダサイズが8バイトと小さい |
| 低遅延 | ハンドシェイクや確認応答のオーバーヘッドがない |
UDPヘッダの構造
UDPデータグラムのヘッダは8バイトのみで、非常にシンプルな構造です。
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 送信元ポート | 宛先ポート |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 長さ | チェックサム |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| フィールド | サイズ | 役割 |
|---|---|---|
| 送信元ポート | 16ビット | 送信側アプリケーションを識別(省略可能) |
| 宛先ポート | 16ビット | 受信側アプリケーションを識別 |
| 長さ | 16ビット | ヘッダとデータの合計長 |
| チェックサム | 16ビット | データの整合性検証(IPv4では省略可能) |
UDPの通信フロー
UDPはコネクションレスのため、データを即座に送信できます。
sequenceDiagram
participant C as クライアント
participant S as サーバー
Note over C,S: 接続確立なし
C->>S: データグラム1
C->>S: データグラム2
C->>S: データグラム3
Note over C,S: ACKなし、再送なしUDPでは以下のことが発生する可能性があります。
- パケットが到達しない(ロス)
- パケットが順番通りに届かない(順序逆転)
- パケットが重複して届く(重複)
これらの問題に対処が必要な場合は、アプリケーション層で対応する必要があります。
TCPとUDPの比較
TCPとUDPの主な違いを表にまとめます。
| 項目 | TCP | UDP |
|---|---|---|
| 接続 | コネクション型 | コネクションレス型 |
| 信頼性 | 保証あり(再送制御) | 保証なし |
| 順序保証 | あり(シーケンス番号) | なし |
| フロー制御 | あり(スライディングウィンドウ) | なし |
| 輻輳制御 | あり | なし |
| ヘッダサイズ | 20~60バイト | 8バイト |
| 速度 | 比較的低速(オーバーヘッドあり) | 高速(低オーバーヘッド) |
| 通信形態 | ユニキャスト | ユニキャスト、マルチキャスト、ブロードキャスト |
flowchart TB
subgraph "TCP"
direction TB
T1[コネクション確立] --> T2[データ転送<br/>確認応答あり]
T2 --> T3[コネクション切断]
T2 -.->|再送| T2
end
subgraph "UDP"
direction TB
U1[データグラム送信] --> U2[データグラム送信]
U2 --> U3[データグラム送信]
endTCPとUDPのユースケース
それぞれのプロトコルは、特性に応じた適切なユースケースがあります。
TCPが適したユースケース
信頼性が重要で、データの欠落や順序の入れ替わりが許容されない場合に使用します。
| プロトコル/アプリケーション | ポート番号 | 理由 |
|---|---|---|
| HTTP/HTTPS | 80/443 | Webページの完全な転送が必要 |
| FTP | 20/21 | ファイルの完全性が重要 |
| SMTP | 25 | メールデータの欠落は許容されない |
| SSH | 22 | コマンドの確実な実行が必要 |
| データベース接続 | 様々 | トランザクションの整合性が重要 |
UDPが適したユースケース
速度や低遅延が重要で、一部のデータ損失が許容される場合に使用します。
| プロトコル/アプリケーション | ポート番号 | 理由 |
|---|---|---|
| DNS | 53 | 小さなクエリで再送オーバーヘッドを避ける |
| DHCP | 67/68 | ブロードキャスト通信が必要 |
| NTP | 123 | 時刻同期は最新値が重要 |
| VoIP(音声通話) | 様々 | リアルタイム性が重要、古いデータは不要 |
| オンラインゲーム | 様々 | 低遅延が重要、位置情報は最新値のみ必要 |
| ストリーミング | 様々 | 遅延より継続再生が重要 |
プロトコル選択のフローチャート
flowchart TD
A[通信要件の分析] --> B{データの完全性が必須?}
B -->|はい| C{順序保証が必要?}
B -->|いいえ| D{リアルタイム性が重要?}
C -->|はい| E[TCP]
C -->|いいえ| F{アプリ層で対応可能?}
D -->|はい| G[UDP]
D -->|いいえ| H{低オーバーヘッドが重要?}
F -->|はい| G
F -->|いいえ| E
H -->|はい| G
H -->|いいえ| EQUICプロトコルについて
近年、GoogleがHTTP/3で採用したQUICプロトコルが注目されています。QUICはUDP上に構築されたプロトコルで、TCPの信頼性機能とUDPの低遅延を組み合わせた特徴を持ちます。
| 特徴 | 説明 |
|---|---|
| UDP上で動作 | ファイアウォールやNATを通過しやすい |
| TLS 1.3統合 | 暗号化が組み込まれ、ハンドシェイクが高速 |
| マルチストリーム | Head-of-Line Blockingを回避 |
| 接続マイグレーション | IPアドレス変更時も接続を維持 |
QUICの詳細についてはRFC 9000を参照してください。
ネットワークコマンドでTCP/UDP通信を確認する
実際の環境でTCPとUDP通信の状態を確認する方法を紹介します。
Windowsでの確認
TCP接続とUDPポートの一覧を確認します。
|
|
出力例:
Proto Local Address Foreign Address State
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 192.168.1.10:52341 93.184.216.34:443 ESTABLISHED
UDP 0.0.0.0:53 *:*
TCPではState列でコネクションの状態を確認できます。
| 状態 | 説明 |
|---|---|
| LISTENING | 接続待ち受け中 |
| ESTABLISHED | 接続確立済み |
| TIME_WAIT | 切断後の待機中 |
| CLOSE_WAIT | 相手からのFIN受信済み |
Linux/macOSでの確認
|
|
tcpdumpでパケットをキャプチャ
より詳細な通信内容を確認する場合は、tcpdumpを使用します。
|
|
まとめ
本記事では、TCPとUDPの違いについて解説しました。
TCPの特徴
- コネクション型プロトコルで、3ウェイハンドシェイクにより接続を確立
- 再送制御、フロー制御、輻輳制御により信頼性のある通信を実現
- オーバーヘッドがあるため、UDPより遅延が大きい
- Webアクセス、ファイル転送、メールなど信頼性が重要な用途に適する
UDPの特徴
- コネクションレス型プロトコルで、即座にデータを送信可能
- 信頼性機能がなく、軽量で低遅延
- ヘッダサイズは8バイトのみ
- リアルタイム通信、DNS、ストリーミングなど速度重視の用途に適する
適切なプロトコルを選択するには、アプリケーションの要件(信頼性、遅延、帯域効率など)を正確に理解することが重要です。
次回の記事では、ポート番号とソケット通信について詳しく解説し、アプリケーション間通信の識別方法を学びます。