Lesson1で見たように,UDPの役割はポート番号を使ってアプリケーション同士を結びつけることだけ。通信の信頼性を高めるような処理は一切しない。
本来,通信というものはできるだけ信頼性を高めるのが理想のはず。TCPを使えば簡単にその信頼性が手に入るのに,信頼性を省いたUDPをわざわざ使うアプリケーションがあるのはなぜなのか。その答えはUDPの「軽さ」にある。
通信路の確立や状態管理が不要
そもそも軽さとは相対的な言葉。つまり,UDPが軽い理由はTCPが重い理由とセットで考えて初めて正しく理解できる。そこでこのLesson2では両者を比較しながらUDPの軽さの意義を探っていく。
UDPがTCPよりも軽い理由は二つある。それは,(1)やりとりするパケットの数が少なくて済むことと,(2)通信ソフトにかかる負荷が小さいこと──である。順番に見ていこう。
まずは,やりとりするパケットの数が少なくて済むことから。これは,UDPとTCPを使ったデータ通信の手順を比べれば一目瞭然だ。
UDPを処理するUDPスタックは,アプリケーションからデータを受け取るとすぐにUDPパケットを作って相手に送る。つまり,1パケットに収まる小さなデータを相手に送り,相手からも同じ1パケットのデータを受け取るようなアプリケーションの場合,UDPなら無駄なく2パケットのやりとりで済んでしまうわけだ(図2-1上の(1))。
一方,TCPでは,相手と通信する際にまず通信路の確立が必要。これだけで三つのパケットのやりとりが発生する(同下の(1))。
続くデータのやりとりはUDPと変わらない(2パケット)が,TCPの場合,さらに通信を終えるときにも切断手続きに4パケット消費する。つまり,たった2パケットのデータをやりとりするために,TCPを使うと9パケットも必要になるのだ。パケットの無駄もさることながら,お互いの距離が離れていればいるほど通信を終えるまでにかかる時間も長くなる。
例えばDNSは,まさに上で示したように1パケットに収まる小さなデータが1往復するだけのやりとりで完了するのが基本となっている。このため,「DNSの通常の問い合わせにUDPではなくTCPを使うなど,無駄が多すぎてありえない」(日本レジストリサービス 技術研究部の民田 雅人氏)のだ。
サーバーの負荷はもっと差がつく
もう一つの軽さの理由である,通信ソフトにかかる負荷についてUDPとTCPを比べてみる。
Lesson1で見たように,UDPスタックはポート番号を管理する以外の処理は何もしない(同上の(2))。送信側のUDPスタックは,アプリケーションからデータを受け取って,ポート番号を書き込んだUDPパケットを送り出したら仕事は終わり。受信側のUDPスタックも,受け取ったパケットをあて先ポート番号を基にアプリケーションに渡したらひと区切りだ。受け取ったパケットをその都度処理するだけなので,それ以外のことにメモリーを消費しない。
一方のTCPは,通信相手との間で通信路(コネクション)を確立したり切断したりする「コネクションの管理」が必要になる(同下の(2))。それぞれのコネクションごとにメモリーを確保してパケットの再送や並び替えといった制御を行う。このため,TCPスタックにかかる負荷はとても大きい。
裏返すと,UDPはこうした処理が必要ないのでTCPよりもずっと軽くなる。とくにサーバーのように多数の相手と同時に通信するケースではその差は圧倒的なのだ。