UDP(User Datagram Protocol)は、IP上で動作し、データグラム送信時に最小限のレイテンシを提供するコネクションレスのデータ転送プロトコルです。TCPとは異なり、UDPは配信、パケット順序、重複防止を保証しません。IETF RFC 768(2024)によると、UDPはビデオ通話、ストリーミング、DNSクエリにより、世界のインターネットトラフィックの40%以上を処理しています。
重要なポイント
UDP(User Datagram Protocol)は、TCP/IPモデルのトランスポート層における主要プロトコルの1つで、1980年にDavid Reedによって設計されました。最小限のデータ転送メカニズムを提供します:アプリケーションがデータグラムを送信し、プロトコルは受信者に届いたかどうかを追跡しません。
UDPヘッダーは、送信元ポート、宛先ポート、長さ、チェックサムの4つのフィールドのみで構成されています。各フィールドは2バイトを占めるため、ヘッダーの合計サイズは8バイトです。比較すると、オプションなしのTCPヘッダーは20バイト、オプションありでは最大60バイトです。
このプロトコルは自身のレベルでのフラグメンテーションをサポートしません。データグラムがMTU(Maximum Transmission Unit)を超える場合、IPレベルでフラグメント化されます。1つのフラグメントが失われると、データグラム全体が破棄されます。これはUDPが個々のフラグメントの再送信を要求できないためです。開発者はデータグラムサイズを制御する必要があります。モバイルネットワークではMTUが1400バイトであることが多いため、最大サイズはこの値を超えないようにする必要があります。
UDPを使用するアプリケーションは、SOCK_DGRAMタイプのソケットを作成し、ポートと宛先IPアドレスを指定してデータグラムを送信します。プロトコルは最小限のヘッダーを追加し、パケットをIP層に渡します。受信者は自身のポートをリッスンし、到着したデータグラムからデータを抽出します。
UDPは輻輳制御を行いません。アプリケーションはネットワークがサポートする最大速度でデータグラムを送信できます。これによりチャネルの輻輳が発生する可能性がありますが、リアルタイムシナリオではこのような積極性は正当化されます。ビデオ通話では、送信を停止するよりも、損失の可能性があるデータストリームの方が重要です。
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b'Hello, UDP!', ('192.168.1.100', 8888))
sock.close()
この例では、UDP用にSOCK_DGRAMソケットが作成されています。sendtoメソッドは接続を確立せずにデータグラムを送信します。受信者のIPとポートを知っているだけで十分です。サーバー側のrecvfromメソッドは、応答用にデータと送信者のアドレスの両方を返します。モバイルプラットフォームのUDPソケットも同様に構成されますが、追加の権限が必要です:iOSでは暗号化されていないUDP接続にNSAppTransportSecurityを追加する必要があり、AndroidではマニフェストにINTERNET権限が必要です。
UDPの選択は、速度が信頼性よりも重要なシナリオで正当化されます。このプロトコルは、接続確立、確認応答、再送信に時間を浪費しません。これにより最小限のレイテンシが実現しますが、開発者が損失を個別に処理する必要があります。
| 長所 | 短所 |
|---|---|
| 低レイテンシ — ハンドシェイクなし | 配信保証なし |
| 小さいヘッダー — 8バイト | 輻輳制御なし |
| ブロードキャストおよびマルチキャスト対応 | パケット重複の可能性 |
| データグラムの独立性 — キューイングなし | データグラムサイズがMTUに制限 |
モバイルアプリケーションでは、UDPはWebRTCなどのフレームワークを介して使用され、UDP上に損失制御、適応ビットレート、ジッタバッファを追加します。これにより、ベアプロトコルの欠点なしに速度の利点が得られます。
UDPのもう1つの重要な側面は、輻輳制御がないことです。TCPでは、Slow StartおよびCongestion Avoidanceアルゴリズムがパケット損失時に送信速度を低下させ、ネットワークの過負荷を回避します。UDPにはそのようなメカニズムがないため、開発者は独自の速度制御戦略を実装する必要があります。例えば、ビデオ通話での適応ビットレートや、ゲームサーバーでの過剰なネットワーク輻輳を防ぐためのレート制限です。
UDPは、レイテンシ許容度がパケット損失許容度よりも重要なシナリオで不可欠です。モバイルおよびWeb開発におけるプロトコルの主な適用分野を見ていきましょう。
UDP上で動作するRTPおよびRTSPプロトコルは、リアルタイムのオーディオおよびビデオストリームの送信に使用されます。WebRTC — ブラウザやモバイルアプリケーションでのビデオ通話の標準 — は、メディアデータの主要なトランスポートとしてUDPを、シグナリングにTCPを使用します。30fpsのビデオで1パケット失われてもユーザーには気づかれませんが、再送信の遅延は画像の顕著なフリーズを引き起こします。
マルチプレイヤーシューティングゲームやMOBAは、適切な同期のために50ms未満のレイテンシを必要とします。UDPはプレイヤーの位置、ショット、イベントをTCPよりも高速に送信し、パケット損失は単に無視されます。次の更新は16~33msで届きます。UnityやUnreal Engineを含む人気ゲームエンジンは、アプリケーションレベルの確認応答によるクリティカルイベントの信頼性を追加した独自のトランスポート層を介してUDPを使用します。
DNSクエリはポート53でUDPを使用します。各クエリは1つの小さなデータグラム(通常512バイトまで)だからです。応答がない場合、クライアントはタイムアウト後にクエリを再試行します。これは3ウェイハンドシェイクによるTCP接続の確立よりも高速です。DHCPもUDP上で動作します。これは、クライアントがまだIPアドレスを持っておらずTCP接続を確立できない一方で、ブロードキャストUDPパケットによりローカルネットワーク上のDHCPサーバーを見つけられるためです。
UDPとTCPの選択は、速度と信頼性のトレードオフです。各プロトコルはタスクのクラスに最適化されており、それらの違いを理解することは、モバイルアプリケーションでのネットワーク通信設計において正しいアーキテクチャ上の決定を下すのに役立ちます。
| 基準 | UDP | TCP |
|---|---|---|
| 接続確立 | 不要 | 3ウェイハンドシェイク |
| ヘッダー | 8バイト | 20~60バイト |
| 配信保証 | なし | あり(確認応答付き) |
| 順序付け | なし | あり |
| 輻輳制御 | なし | あり(AIMD、Slow Start) |
| 使用例 | ストリーミング、ゲーム、DNS | Web、メール、ファイル、API |
モバイルプロジェクトでは、信頼性の高いリクエスト(認証、データ読み込み)にTCP、メディアストリームにUDPというハイブリッドアプローチがよく使用されます。QUIC — UDP上で動作するGoogleの最新プロトコル — は、UDPの速度とTCPの信頼性を組み合わせ、HTTP/3ですでに使用されています。
クライアントからメッセージを受信して応答を送信する、PythonでのシンプルなUDPサーバーを見てみましょう。サーバーはポート8888をリッスンし、無限ループで着信データグラムを処理します。
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('0.0.0.0', 8888))
print('UDPサーバーがポート8888で起動しました')
while True:
data, addr = server.recvfrom(1024)
print(f'{addr}から受信:{data.decode()}')
server.sendto(b'OK', addr)
サーバーはUDPソケットを作成し、ポート8888にバインドして、着信データグラムを待機します。recvfromはデータとクライアントのアドレスを返し、sendtoを介した応答を可能にします。TCPとは異なり、サーバーは接続状態を維持しません。各データグラムは独立して処理されます。これにより、UDPサーバーはスケーラブルになります。1台のサーバーで、個々の接続ごとにメモリを割り当てることなく、数百万のクライアントを処理できます。これはDNSサーバーやゲームのマッチメイキングシステムにとって重要です。
モバイル開発では、UDPは高レベルライブラリを介して使用されることがよくあります。例えば、iOS用のCocoaAsyncSocketは、非同期イベント処理のためのデリゲートとGCDを備えたUDPソケットを提供します。Androidでは、DatagramSocketクラスは標準のjava.netライブラリの一部であり、追加の依存関係は必要ありません。Flutterには、ネイティブソケットを設定せずにデータグラムを送受信するためのシンプルなインターフェースを提供するudpパッケージがあります。
多くのモバイルネットワークや企業ファイアウォールは、特に1024以上のポートでUDPトラフィックをブロックすることに注意することが重要です。アプリケーションがUDPを使用する場合、WebRTCが行うように、TCPへのフォールバックを提供するか、STUNサーバーを介してプロトコルの可用性を確認する必要があります。iOSでは、システムのNetwork.frameworkとNWConnectionがTCPとUDPの両方をサポートし、可用性に基づいて最適なプロトコルを自動的に選択します。リアルタイムアプリケーションでは、パケット損失時にストリーム品質を低下させる適応ビットレートを実装することも推奨されます。これにより、エラー率の高い不安定なチャネルでも継続的な再生が保証されます。
よくある質問
UDPは接続を確立せず、パケット配信を保証しません。そのためTCPよりも高速です。UDPヘッダーは8バイトで、TCPは20~60バイトです。UDPはストリーミングやゲームに適しており、TCPはWebリクエストやファイル転送に適しています。
データグラムは、UDPヘッダー(送信元ポート、宛先ポート、長さ、チェックサム)を持つ独立したデータパケットです。各データグラムは、以前のものと関連なく独立して処理されます。データグラムサイズはネットワークMTUによって制限され、仕様上は最大65507バイトです。
UDPはトランスポートレベルでの信頼性を提供しません。信頼性はアプリケーションによって実装されます。開発者は、シーケンス番号、チェックサム、再送要求、エラー訂正を追加します。FEC(前方誤り訂正)により、再送信なしで失われたパケットを復元できます。
UDPはデータ整合性が重要なシナリオには適していません:ファイル転送、銀行取引、REST APIなどです。これらの場合、TCPはすべてのバイトが正しい順序で届くことを保証します。また、損失率の高い不安定なチャネルではUDPは推奨されません。
QUICはUDP上で動作するトランスポートプロトコルで、Googleによって開発され、IETFによってRFC 9000として標準化されました。UDPの速度とTCPの信頼性を組み合わせ、ヘッドオブラインブロッキングなしの多重化をサポートし、組み込みの暗号化を備えています。HTTP/3はトランスポート層としてQUICを使用しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。