UDPとは|仕組み・ヘッダ・特徴・用途・実装対策をわかりやすく解説

UDPとは

UDP(User Datagram Protocol)は、インターネットプロトコルスイート(TCP/IP)のトランスポート層に属するプロトコルの一つで、接続を確立せずにデータグラム(パケット)を送受信する「コネクションレス型」の通信方式を提供します。RFC 768(1980年)で定義され、シンプルでオーバーヘッドが小さい点が特徴です。TCPのような再送・順序制御・フロー制御・輻輳制御を持たず、遅延・オーバーヘッドを低減したい用途で広く使われています。

UDPの基本的な仕組みとヘッダ構成

UDPは非常にシンプルなヘッダ(固定 8 バイト)をもちます。ヘッダのフィールドは次のとおりです。

  • 送信元ポート(16ビット)— 送信元アプリケーションのポート番号(任意、0 は通常予約)
  • 宛先ポート(16ビット)— 受信側アプリケーションのポート番号
  • 長さ(16ビット)— UDPヘッダ+データのバイト長(最小8、最大65535)
  • チェックサム(16ビット)— データと疑似ヘッダ(IPアドレス等)に基づく整合性チェック。IPv4ではオプション(ゼロは非使用を示すことが許される実装がある)が可能、IPv6では必須

UDPのデータグラムはIPパケット内にカプセル化され、IPのルーティングと配達機能に依存します。したがって、UDP自体に接続管理の概念はなく、通信相手の状態情報を長期間保持しません(ステートレス)。

主な特徴(利点と欠点)

  • 利点
    • 低いオーバーヘッド:ヘッダが小さくコネクション確立が不要
    • 低遅延:リアルタイム性が求められる音声・映像やゲームに向く
    • マルチキャスト/ブロードキャストのサポート(IPレベルのマルチキャストと組合せ)
    • アプリケーション側で自由に信頼性・順序保証を設計できる
  • 欠点
    • 信頼性(再送・順序保証)がないためパケットロスや順序入替に弱い
    • フロー制御・輻輳制御がないためネットワーク混雑時の挙動を自分で管理しないと問題になる
    • 大きなデータはIPレベルでフラグメントされることがあり、断片の損失で全体が失われる

代表的な用途

  • リアルタイム通信:VoIP(RTP)、ビデオ会議、ライブストリーミング(低遅延が重要)
  • DNS:クエリ応答は通常UDP(ポート53)、大きな応答やゾーン転送はTCPへフォールバック
  • DHCP:ブロードキャストを伴う設定(ポート67/68)
  • SNMP、TFTP、ゲームの状態同期など、短い問い合わせや低遅延を優先する用途
  • 現代ではQUIC(HTTP/3など)はUDP上で独自に信頼性・輻輳制御を実装している—UDPは信頼性を必須としない「下地」として使われている

UDPヘッダとチェックサムの詳細

UDPチェックサムは、UDPヘッダとデータだけでなく、IPの疑似ヘッダ(送信元・宛先IPアドレス、プロトコル番号、UDP長)を含めた計算を行います。これにより、IPヘッダの重要フィールドの誤り検出にも役立ちます。

実装上の注意点:

  • IPv4ではチェックサムが“0”で送られることを許容する実装があるため、完全に必須ではない(ただし推奨はされる)
  • IPv6(RFC 8200)ではUDPチェックサムは必須で、チェックサム値0は有効な値として扱われるため回避策はない
  • UDPの長さフィールドは16ビットなので、UDPで扱える最大のデータ長は理論上 65535バイト(ヘッダ含む)。IPv4ヘッダ(最小20バイト)を除いた有効ペイロードは通常最大 65507 バイト(65535 − 20 − 8)です。IPv6では固定ヘッダが40バイトのため、最大ペイロードは若干小さくなります(通常 65487 バイト)。

信頼性が必要な場合の対策(アプリケーションレイヤでの実装手法)

UDP自身に再送や順序制御がないため、アプリケーション側で必要に応じて次のような手法を実装します。

  • ARQ(Automatic Repeat reQuest):受信確認(ACK)とタイムアウトによる再送
  • シーケンス番号:受信側で順序復元や重複排除を行う
  • FEC(Forward Error Correction):冗長データを送り、パケット損失を補う(遅延の上限が厳しいストリーミングで有用)
  • ジッタバッファ:受信側で遅延のばらつきを吸収して再生品質を上げる(音声/映像)
  • アプリケーションレベルの輻輳制御:ビットレート制御、適応ストリーミング(例:DASHとは別だが同様の原理)

NAT・ファイアウォールとUDP

UDPはステートレスなので、NATやファイアウォールは「擬似的な接続情報」を接続追跡テーブルで保持して対応します。よくある挙動:

  • NATは最初の送信を見て外向けポートを割り当て、一定時間(短め)そのマッピングを保持する。アイドルタイムアウトが短く、長時間の双方向未通信だとマッピングが破棄される。
  • パケットの到着方向が逆の場合、事前にマッピングがなければブロックされる(ファイアウォールが許可していない場合)。
  • STUN/TURN/ICEなどのプロトコルは、NAT越えでUDPを使うための仕組みを提供する(WebRTC等)。

パケットサイズとフラグメンテーションの注意

UDPが送る大きなデータグラムはIPレイヤでフラグメントされる可能性があります。フラグメントのいずれかが失われると全体が復元できずデータは破棄されます。したがって現代の実装では、MTU(一般に Ethernet の1500バイト)以下にパケットを分割して送るか、Path MTU Discovery を利用してIPフラグメンテーションを避けることが推奨されます。

UDPと代替プロトコル/発展

  • TCP:信頼性重視のストリーム指向プロトコル。UDPと比較してオーバーヘッドが大きいが信頼性が高い。
  • QUIC:UDP上で動作するトランスポートで、TLS統合の暗号化、ストリーム多重化、独自の輻輳制御を提供(HTTP/3の基盤)。RFC 9000など。
  • SCTP:メッセージ指向でマルチストリーム・マルチホーミング対応の信頼性プロトコル(RFC 4960)。
  • UDP-Lite:部分的なチェックサムを許容し、エラーの許容が映像配信などで有効なケースに使われる(RFC 3828)。

実装上の基本(ソケットAPIの視点)

一般的なBSDソケットAPIでは、UDPは以下のように扱います。

  • 送信:sendto() や sendmsg() を使う。宛先を指定して1回の呼出しで1つのデータグラムを送る。
  • 受信:recvfrom() や recvmsg() で1つのデータグラム単位で受け取る(バッファが足りないと切り捨てられる)。
  • 仮想的な「connect」:connect() を呼ぶと、カーネルがデフォルトの送信先を固定し、recv()/send() を使えるが、プロトコル自体は依然としてコネクションレス。

まとめ

UDPは「シンプルさ」と「低オーバーヘッド」を武器に、リアルタイム通信や短い問い合わせ系のプロトコルで幅広く用いられます。欠点である信頼性や輻輳制御の不足は、用途に応じてアプリケーション層や新しいトランスポート(QUIC等)で補うのが実務上の常套手段です。UDPの性質を理解して適切に使うことで、高速・低遅延な通信を実現できます。

参考文献