連載
» 2003年10月09日 00時00分 公開

基礎から学ぶWindowsネットワーク:第13回 データグラム通信を実現するUDPプロトコル (2/4)

[デジタルアドバンテージ,著]

 UDPは、TCP/IPプロトコルにおいて、「データグラム通信」を実現するためのトランスポート層プロトコルである(「データグラム・サービス」と「セッション・サービス」の違いについては「連載第3回―2.NetBIOSの2つのデータ通信サービス」などを参照)。具体的には、IPプロトコルを直接、ほとんどそのまま利用した通信プロトコルであり、IPプロトコルとほぼ同じ機能を上位のアプリケーション・プログラムに対して提供している。1回の通信で(1つのUDPパケットで)、(デフォルトでは)最大64Kbytesの、ひとかたまりのデータを、指定されたコンピュータ上の指定されたアプリケーションにまで届けることができる。ただしIPプロトコルとは異なり、パケットのフラグメンテーション(が行われているかどうか)やネットワーク・インターフェイスのMTUサイズ(の制約による送信の失敗)、ルーティング経路(の設定によるパケットの到達可能性の可否など)といった事柄にとらわれることはない。それらはすべてIPプロトコル・レベルで解決される問題であるからだ。

 UDPの持つ機能としては、次のようなものが挙げられる。

■コネクションレスのデータグラム通信機能の提供
 UDPでは、通信に先立つ事前の通信路のセットアップや、通信完了時に終了処理などが不要な、コネクションレスのサービスを提供している。そのため、利用するのが容易である。また、パケットの送信に関しても、送信順序の制御などが不要であり(先に送ったパケットが正しく相手に届いているかどうかなどを気にしなくてもよい)、パケットを次々と送信することができる。

 またコネクションレス型プロトコルなので、「ステートレス(stateless)なサービス」を実装しやすいという特徴がある。例えばtelnetやSMTP、ftp、POPなどのプロトコルはTCPを使っているので、何らかの理由で通信が途絶えた場合(どちらか一方がダウンしたり、長い間通信路が切断したりした場合)、TCP接続が切られてしまうのを経験したことはないだろうか。TCP接続がいったん途切れると、同じ状態(ステート)から再接続することはできず、ユーザーはサービスへ最初から接続し直すことになる(例:telnetならば、最初のログオンからやり直すしかない)。これに対してUDPでは、内部に以前の状態(ステート)を持っていないので(これを「ステートレス」という)、サービスを同じ場所から再開しやすくなっている。例えばUNIXシステムでよく使われるNFS(Network File System)ファイル共有プロトコルはUDPを利用しており、システム障害からの復旧が容易になっている(注:NFSプロトコル自体もなるべくステートレスになるように作られている。ただし現在のNFS Ver.4ではTCPでも利用できるなど、改良されている)。

■高速、軽量な通信
 UDPではIPプロトコルの機能をほぼそのまま利用しているだけである。UDPでパケットを送信すると、それはIPパケット上に載せられ、通信相手のマシンへと届けられる。途中でIPフラグメンテーションが起こっても、最終的には1つのUDPパケットとして再構成され、相手のアプリケーションへと届けられる。途中で再送や送達確認(相手に届いたかどうかを確認すること)は行われないので、最小限のオーバーヘッドで通信相手へと届けることができる。つまり非常に高速で軽量な(=ネットワーク的にも内部処理的にも負荷が少ない)プロトコルといえる。

■1対1だけではなく、1対多の通信機能提供
 一般的な通信では、1対のマシン(および、その上で稼働しているアプリケーション)同士で、1対1で通信するのが普通である。だが、UDPでは、同時に複数の相手に対して、1回の送信動作で同じデータを送ることができる。これを「同報通信」という。UDPでは、ネットワーク上のすべてのマシンを対象としたブロードキャスト通信と、1組のグループを対象としたマルチキャスト通信を行うことができる。

 以上のようなメリットがある一方で、次のようなデメリット(というよりも、IPプロトコルの特性とでもいうべきか)も存在する。

■信頼性のない通信
 IPプロトコルにおける通信は「信頼性のない通信(unreliable communication)」である。だから、IPパケットをそのまま利用しているUDPでも、IPパケットと同じく、「信頼性のない通信」となる。ここでいう「信頼性がない」とは、「データが化ける」などという意味ではない。送信したUDPパケットが相手にまで届いたかどうかは送信元では分からない(「送達確認」がない)ということである。また途中のネットワークの混雑具合によっては、送信側で送信した順番にUDPパケットが相手に届くという保証もないし(到着順序が入れ替わることがある)、途中でUDPパケットが何らかの理由で消失しても誰も再送処理を行ってくれない。

 このような特性は非常に大きなデメリットのように思われるかもしれないが、これらの処理をしないからこそ、高速、軽量なプロトコルになっているのである。送達確認や到着順序の保証が必要であれば、それはアプリケーション自身で行う必要がある。

■バッファリングなどは行われない
 UDPでは、送信するデータの結合やバッファリングなどは行われない。例えば100bytesのデータ部を持つUDPパケットを10回送信すれば、それは10個のUDPパケット(つまり10個のIPパケット)となって相手に送信される。10パケット分のデータを結合して、1000bytesのデータ部を持つ1つのUDPパケットに再構成されたりはしない。パケットの数を少なくしてパフォーマンスを向上させたければ、やはりアプリケーション自身で対応する必要がある。

UDPの利用方法

 以上のような特性があるため、TCPとは違って、UDPは次のような通信に向いている。

軽量なネットワーク・サービス―1対1の通信(処理の依頼と応答)

 ネットワーク・サービスでは、あるコマンドを受け取って、それに対する応答を返す、というものが多い。いわゆるクライアント/サーバ方式のアプリケーションである。だが、もしこのコマンドや応答が、いずれも1パケットに入ってしまうくらい小さなものだとしたらどうだろうか。このようなサービスの場合には、いちいち事前にセッションの確立や終了処理が必要なプロトコルではムダ(オーバーヘッド)が多いだろう。このような用途では、UDPが最適である。

1対1の通信(処理の依頼と応答)
最も基本的な通信の形態。クライアントからサーバに対して処理を要求する(コマンドを送る)と、サーバはそれに対する応答を返す。もしコマンドもその応答も(1パケットに収まるぐらい)小さければ、そして1回のやりとりだけで処理が終わってしまうようならば、UDPを利用するとよい。最小限のオーバーヘッドで通信を済ませることができる。TCPならば、コネクションの最初の段階(セッションをオープンする段階)だけで、すでに3パケットも往復してしまう。
 (1)クライアントからサーバに対するコマンド(処理の要求)の送信。
 (2)サーバからの応答(コマンドに対する結果)の送信。

 このようなサービスの例としては、DNSサービスなどが挙げられる。DNSサービスは、FQDN名を渡して、それに対応するIPアドレスを返すサービスである。DNSの要求コマンドもその応答も、いずれも1パケットもあれば十分なので、UDPが使われている。もしDNSサーバのIPアドレスが間違っていたり、DNSサーバの負荷が高くて応答が一定時間以内に得られなかったりした場合は、再度DNSのコマンドを送信するのが普通である。これにより、信頼性のない通信にも対処している。

 このほかにも、UDPプロトコルの単純性を利用した例として、TFTP(trivial file transfer protocol)やBOOTP/DHCP(bootstrap protocol/dynamic host configuration protocol)プロトコルなどが挙げられる。これらのプロトコルは(ディスクレスの)コンピュータ・システムの起動時に使われることが多いプロトコルであり、UDPのようなシンプルなプロトコルでなければならない。システムが起動時に実行するBIOS-ROMファームウェアは容量が限られており、TCPのような複雑なプロトコルではROM内に実装するのが困難だからだ。BIOS-ROM中に格納されたIPとUDPのプロトコル・スタックは、自分自身のIPアドレスを決定するためにBOOT/DHCPを利用する。いったんIPアドレスが決まれば、次はTFTPプロトコルを使ってOSシステムのイメージをTFTPサーバからダウンロードし、OSを起動する。このような目的のため、TFTPやBOOTP/DHCPでは、1つのUDPパケットのサイズを512bytes(とヘッダ)程度に抑え、IPフラグメントがおきないようにプロトコルが設計されている。IPフラグメントの処理が必要なければ、IPプロトコルの処理も大幅に簡略化して、BIOS-ROM中に格納しやすくなる。

送達確認の不要なサービス―1対1の通信(情報の送信のみ)

 ネットワーク・サービスには、一方的に情報を相手に伝えるだけという種類の通信がある。例えば、システムに異常が起こったことをあらかじめ決められたマシンへ通知するというサービスである。このようなケースでは、送信元のシステムは、エラーを送信してすぐにシャットダウンしたり、再起動したりする。エラーを送信したからといって、送信した相手からいちいちその応答などを送ってもらう必要などないだろう。

 また、自身が正常に動作していることを一定時間間隔で相手に通知するというようなサービスも考えられる。この場合も、送信結果に対していちいち応答をもらう必要はない(受信側では、一定時間ごとの通知が来なくなってから何らかのアクションを起こせばよい)。

 このような、一方的に情報を送信するだけのサービスにもUDPが向いている。具体的には、SNMPのトラップの送信(システムがある状態に陥った場合に、自動的に管理用メッセージを送信する機能)や、syslog(システムの状態を、特定のマシンへ報告する機能。UNIXなどで広く使われている)などでこのタイプの通信が使われている。

1対1の通信(情報の送信のみ)
情報を一方的に送信するだけの通信。エラー情報やアラート情報を送信したり、定期的に自分自身の状態(ログ・データなど)をログ記録サーバへ送り付けたりする場合に向いている。1パケットしか送らないので、いちいち事前にセッションのセットアップなどが必要なコネクション型通信では、やはりオーバーヘッドが大きくなる。
 (1)情報をUDPパケットに入れて、受信側へ送信する。このような用途では、送達確認(相手に届いたことを了承するための応答)は不要なことが多い。また一定時間ごとに繰り返し送信するような通信でも、送達確認は不要なことが多い(何回か失敗したとしても、また後で送信するから)。

多数の相手に情報を伝えるサービス―1対多の通信(同報通信)

 同時に複数の相手に対して、情報をいっせいに送信したいというネットワーク・サービスも、UDPに向いている。例えばネットワーク上のすべてのマシンに対して、最小限のオーバーヘッドで同じ内容のメッセージを送信するためにUDPのブロードキャスト/マルチキャスト通信を使うことができる。1回の送信動作で、すべてのマシンに対してデータを送ることができるので、ネットワークのトラフィックが最小で済むし、いちいち各通信相手に対してセッションのセットアップなどの操作が不要になり、システムやネットワークの負荷を抑えることができる。ただしこのタイプの通信では、応答を受け取るのが難しいし、いっせいに応答を受け取ると受信側の負荷が高くなってしまう可能性がある。そのため、一方的に情報を送信するだけで済む場合とか、送信失敗時の再送処理の不要な情報の伝達などに向いている。

 このタイプの通信のもう1つのメリットとして、通信相手を特定する必要がない、ということが挙げられる。相手のマシンが生きているかダウンしているかにかかわらず情報を送ったり、通信相手が実際に何台いるかにかかわらず、最小限のオーバーヘッドで情報を送信したりできる。ただし確実に相手にまで届いているという保証はないので、同じ情報を(一定時間ごとに)繰り返し送信して通信の信頼性を上げることが可能なものや、少々欠落してもよいような情報の伝達に向いている。

 このタイプの通信の具体的な例としては、ルーティング情報のアドバタイズ(広告。ルータに対して、最新のルーティング・テーブル情報などを伝えること)や、オーディオ/ビデオのマルチキャスト・ライブ送信などが挙げられる。

1対多の通信(同報通信)
複数の相手に対して、いっせいに同じデータを送信するという通信形式。1回の送信操作で、複数の相手に送信することができる。ブロードキャストは同じネットワーク上のすべての相手に対する送信、マルチキャストは特定の(マルチキャストを受信可能として)グループに対する送信という違いがある。これらの違いについては「第8回―1.IPアドレスのクラス」や「第8回―3.さまざまなIPアドレス」を参照。
 (1)1回の送信で、同時に複数の相手にデータを送信することができる。

  

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。