UDP を使ってみよう (1)

前へ << モジュールを使って POP3 クライアントを作ってみよう UDP を使ってみよう (2) >> 次へ

UDP とは

UDP とは、User Datagram Protocol の略です。 TCP (Transmission Control Protocol) は信頼性を提供するプロトコルですが、 UDP はそうではありません。

これまで HTTP・POP3・FTP などのプロトコルを使ってきましたが、 これらは全て TCP を利用していました。送信したいときは

print SOCKET "hoge\n";
と書き、受信したいときは
$buf = <SOCKET>;
としていました。しかし陰では OS が TCP を使って信頼性を保証するためのさまざまなチェックが行なっていたのです。

OS はいったい何をやっていてくれたのでしょうか? それは以下のようなことです。

  1. データの送り先が存在するかどうかのチェック
  2. データ化けの修正
  3. データの順序の保証
  4. データ損失時の再送信
  5. 相手がデータを受信したかどうかの確認
  6. 大量データの分割送信
これは TCP が提供する機能です。TCP を使ったおかげて、 上記のような処理をアプリケーション側で実装する必要がなくなり、 プログラマが楽することができたのです。

一方 UDP が提供する機能はというと、

  1. 化けたデータの破棄 (修正ではない)
これだけです。だからこそ UDP は信頼性を提供しないプロトコル なのです。

TCP の方がいいんじゃないの?

信頼性がないより信頼性がある方がいいに決まっています。 「TCP の方が優れたプロトコルじゃない?」と思う方も多いでしょう。 しかし、要は使いどころなのです。

UDP にもメリットがあります。それは TCP より軽い ことです。

TCP が信頼性を保証できるのは、データを送受信するたびに相手側と

「さっき送ってくれたデータ、ちゃんと受け取ったよー」
「さっき送ったデータ、受け取ったって返事がこないからもう一回送るよ」
「このデータ、中身が化けてるみたいだからもう一回送って」

というふうに確認用パケットを送りあっているからです。

UDP はこんなことをしません。データを受け取ったことをわざわざ伝えませんし、 再送の要求もしません。中身が化けていたら捨てるだけです。 しかしその分処理が少なくてすむのです。

UDP の使いどころ

UDP は以下のような部分で利用されています。
DNS ホスト名を IP アドレスに変換する際、DNS サーバに送るリクエストは UDP です。 DNS サーバからの返事も UDP で返ってきます。つまり、gethostbyname 関数を呼ぶと、 UDP で通信が行なわれているのです。

DNS が UDP を使う理由は、リクエストもレスポンスもサイズが十分小さいこと。 DNS は頻繁に利用されるため、 少しでも軽い処理にしたかったことではないかと思われます (当ページ管理人の推測)。

NFS NFS とは、UNIX でファイルを共有する仕組みです。 NFS を使えば、他のマシンに繋がっているハードディスクを読み書きできます。

NFS が UDP を使っている理由は、 ファイル共有は LAN 内に限定されていることが多く (インターネット経由でファイルを共有することは少ない)、 エラー発生やデータの損失の頻度が少ないためだと思われます。

ただし、NFS プロトコルのバージョン (NFSv2 以降かな?) によっては、 TCP で接続することもできます。

ネットゲーム Diablo・リネージュ・Ultime Online・FINAL FANTASY XI などのネットワークゲームは 少しでも速度を稼いでリアルタイム性を確保するため、UDP を使うものが多いようです。 ただし、ほとんどのゲームは TCP も併用しています。これは速度を稼ぐ部分と、 それほどレスポンスを求めない部分 (プログラムアップデートやログイン処理など) で使い分けをしているものと思われます。
TCP を使ったプロトコルは HTTP、POP、IMAP、SMTP、TELNET、SSH などなど山のようにありますが、それに比べると UDP の利用例は比較的少ないです。 TCP を使うと楽ができるわけですから、それも仕方のないことでしょう。

もし何か新しいプロトコルを作ろうとしていて、TCP よりも UDP の方がいいんじゃないかと考えている場合、 TCP が保証する信頼性を捨てるだけのメリットがあるか? をよく考えてみてください。

前へ << モジュールを使って POP3 クライアントを作ってみよう UDP を使ってみよう (2) >> 次へ