UDPを使う
ここでは、rubyを使ってUDPによる通信をする方法を説明したいと思います。
UDPとは
UDPはデータが宛先に届いたかどうかをUDPは関知しないため、TCPと異なりデータの到着を保障しません。 そのため、UDPを使った通信を行うプログラムを書く場合には、パケットがネットワークの途中で消えてしまうことも想定しなくてはなりません。 このような制約がUDPにはあるため、確実にデータを届けたいアプリケーションではTCPを使うのが一般的です。
このように書くとUDPは使いにくいだけに思えますが、利点もあります。
- 複数の相手に同時にデータを送信できる(ブロードキャスト、マルチキャスト)
- TCPよりもリアルタイム性が高い
まず、第一の利点として複数の相手に同時にデータ送信ができる事が挙げられます。 IPの通信形態には、ユニキャスト、ブロードキャスト、マルチキャストの3種類があります。 (ただし、IPv6にはブロードキャストはありません。) TCPでは、1対1の通信しかできないのでユニキャストしかサポートしていません。 UDPでは、一つデータパケットを送ればネットワークで必要に応じて増やして送ってくるブロードキャストやマルチキャストが利用できます。 ブロードキャストやマルチキャストを利用すると、送信側のアプリケーションの負荷を大きく軽減できます。
第二の利点としてはリアルタイム性が挙げられます。 TCPはデータの到着を保障するため、ネットワークでパケットが消えると再送します。 この再送によって、リアルタイム性が損なわれる事があります。 また、TCPはネットワークが混雑しているとデータ送信量を減らす輻輳制御を行います。 この輻輳制御によってもTCPのリアルタイム性が損なわれています。 リアルタイム性を損なう再送や輻輳制御がUDPにはないため、UDPはTCPよりもリアルタイム性が高くなります。
UDPには、上記のようなTCPにない利点があります。 UDPは、これらの利点を生かしたアプリケーションに使われるのが一般的です。 UDPを使った一般的なアプリケーションとしては、例えば、映像や音声のストリーミングや、IP電話などのVoIP(Voice over IP)などが挙げられます。 音声などを使って通話をするアプリケーションは、全ての音が正しく届く事よりもリアルタイム性が重要視されます。
UDPプログラミング
UDPの通信では、TCPのように接続を確立してから通信を行いません。 そのため、直感的にどちらがサーバだかわからない場合があります。 ここでは「サーバ、クライアント」という表現はせずに、「UDP送信プログラム、UDP受信プログラム」という表現をしたいと思います。
UDPによる通信を行うプログラムの書き方は受信と送信で異なります。 以下に、UDP受信とUDP送信のプログラム作成手順概要を示します。
UDP受信
- ソケットを作る
- bindするIPアドレスとポートを設定する
- ソケットに名前をつける(bindする)
- データを受け取る
UDP送信
UDP送信プログラムは、特定のIPアドレス+UDPポート番号で待っているサーバに対してパケットを送信します。
- ソケットを作る
- 宛先を指定して送信する
単純なUDP受信プログラム
rubyを使った簡単なUDP受信プログラムのサンプルを以下に示します。 コードを簡単にするため、エラー処理は省いてあります。 実際にコードを書く場合にはエラー処理も行ったコードにして下さい。
#!/usr/bin/ruby
require "socket"
udps = UDPSocket.open()
udps.bind("0.0.0.0", 10000)
p udps.recv(65535)
udps.close
上記UDP受信プログラムは、UDP送信プログラムから送られてきたデータを表示して終了します。
単純なUDP送信プログラム
rubyを使った簡単なUDP送信プログラムのサンプルを以下に示します。 コードを簡単にするため、エラー処理は省いてあります。 実際にコードを書く場合にはエラー処理も行ったコードにして下さい。
#!/usr/bin/ruby
require "socket"
udp = UDPSocket.open()
sockaddr = Socket.pack_sockaddr_in(10000, "127.0.0.1")
udp.send("HELLO", 0, sockaddr)
udp.close
上記UDP送信プログラムは、UDP受信プログラムに対してデータを送信して終了します。 上記UDP送信プログラムの動作を確認するためには、あらかじめUDP受信プログラムを起動しておく必要があります。