9.9. UDP -- パケットを送って最善を祈る

UDP(User Datagram Protocol)は、トランスポート層が提供する 2 つのサービスのうちより単純なものです。各 UDP 送信は 1 つの データグラム -- IP とポート宛てに送られる自己完結型のバイトのかたまり -- であり、単独でネットワークに投入されます。プロトコルは可能であればそれを配信します。できなければ再試行せず、送信側に警告もせず、データグラム間の順序も一切保持しません。

9.9.1. UDP が IP に追加するもの

UDP は IP の上の薄い層です。生の IP 配信に 3 つのものを追加します。

  • 両端の ポート番号。これにより、データグラムを宛先ホスト上の単なるホストではなく、適切な プログラム に配信できます(ポート を参照)。

  • 受信側がペイロードを正確に何バイト読み取ればよいかを知るための 長さフィールド

  • ヘッダーとペイロードにわたる 小さなチェックサム。これにより受信側は破損したデータグラムを検出して破棄できます。

それだけです。IP が行ったこと、行わなかったことのその他すべてを UDP は引き継ぎます。データグラムは再試行されません。順序どおりでなく到着することがあります。基盤となるネットワークのクセによって重複することがあります。ネットワークが輻輳していたり、宛先のバッファが満杯だったり、途中のルーターの 1 つがそう判断したりすると、何の通知もなくドロップされることがあります。

左に送信側、右に受信側のある図。送信側から受信側へ 3 本の矢印が向かい、「datagram 1」「datagram 2」「datagram 3」とラベル付けされている。datagram 2 の矢印は X 印の付いた破線として示され、損失を表している。

各 UDP データグラムは独立して送信されます。途中で 1 つが失われても、送信側にも受信側にも何も伝えられません -- そのギャップは無言です。

9.9.2. なぜそれを使うのか

UDP がそれほど信頼できないなら、そもそもなぜ存在するのでしょうか。理由は 3 つあります。

  • 速度とオーバーヘッド。 UDP 送信は 1 つのパケットが出ていくだけです。ハンドシェイクも、確認応答も、維持すべき接続状態もありません。レイテンシと帯域幅のコストは最小限です。

  • 独立したメッセージ。 一部のトラフィックは ステータス更新 のストリームであり、すべてのメッセージが新しいスナップショットで、古いものは無価値です。「私はまだ生きています、これが現在の測定値です」と毎秒公開するカメラは、各 新しい 測定値を配信することを気にかけるのであって、失われた測定値を再生することは気にかけません。

  • マルチキャスト。 1 つの UDP データグラムを一度に多数の受信側へ送信できます。(TCP はそれができません。すべての TCP 接続はちょうど 2 つのエンドポイント間のものです。)サービスディスカバリ、多数のリスナーへのテレメトリ、ビデオストリーミングに有用です。

ネットワークが良好で、送信側の損失への許容度が高い場合、UDP は正しい答えです。配信と順序を保証しなければならない場合、UDP はその上にもう一層の信頼性が必要になるか、あるいはアプリケーションは単に代わりに TCP を使うべきです。

9.9.3. 使うべき でない 場合

逆についても明確にしておく価値があります。UDP が間違った選択となるのは次の場合です。

  • すべてのバイトが重要。 設定データ、コード更新、署名付きトランザクション -- バイトが 1 つ欠けると結果が誤りになるあらゆるケース。

  • 順序が重要。 UDP データグラム 2 がデータグラム 1 より先に到着することがあります。

  • メッセージが大きい。 大きなペイロードはアプリケーションによってより小さなデータグラムに分割する必要があります。トランスポート層はそれをやってくれません。どれか 1 つでも失われると、メッセージ全体が不完全になります。

これらのいずれかに当てはまる場合は、代わりに TCP に頼りましょう。

9.9.4. カメラでの具体例

実際の場面における UDP トラフィックのカメラ側の例。

  • ディスカバリ。 カメラは起動時にローカルネットワークへ「誰がいますか」というデータグラムをブロードキャストし、他のデバイスが応答します。

  • テレメトリ。 毎秒 1 回、カメラは現在のセンサーの測定値を含む小さなデータグラムを収集側に送ります。たまにサンプルを失っても、どのみち次のものが 1 秒後に到着するので問題ありません。

  • 時刻同期。 NTP(ネットワークタイムプロトコル)は UDP 上で動作します。クライアントが小さなリクエストを送り、サーバーが現在時刻で応答します。応答が失われた場合、クライアントは単に後でもう一度尋ねるだけです。

  • DNS 検索。 ネットワークに「この名前はどの IP に対応するか」を尋ねるのは UDP 上で行われます。(名前と DNS で扱います。)

データグラムを送受信するための Python API は、トランスポート層の残りの話が整った後で UDP ソケット にあります。