User Datagram Protocol
1つのUDPパケットで運ぶことのできるデータは、下位層のIPパケット長の制約を受けます。
まず標準のIPパケットでは、
1回の送信で、最大では65515bytes(65535bytesから、IPヘッダの最低サイズ20bytesを引いた値)の
データを送信できます。(IPヘッダ・オプションが付くと、さらに小さくなる)。
よって、その中のデータに入っているUDPパケットが65515bytesとなる訳ですが、
UDPヘッダーのサイズが8bytes固定長で、これで減算した65507bytesがUDPの最大データ長になります。
なお、チェックサムの計算ではUDPヘッダー(8bytes)+擬似ヘッダー(12bytes)
なので、計65527 bytesです。
UDP ではサムチェックよりパケットに破損がないか調べられます。
しかし、それでエラーを検出しても、単にそのパケットを破棄するだけです。
またパケットの順序が違ってもそれを並べ替えることもしません。
パケットを紛失してもそれを知るすべもありません。
ですがUDP で受け取ったデータは、とりあえず破損していないものとなります。
UDPSndTest.javaで、UDPRecTestのプログラムを呼び出すことで、一つのプログラムにまとめたプログラムにする検討をしてみよう。
例えば、 UDPSndTest.java の出力の繰り返しの直前で、
UDPRecTest.main(null);
UDPRecTestのmainを実行させてみよう。
(UDPSndTest.java の中に、UDPRecTest.javaのソースをコピーする必要は
ありません。UDPRecTestのクラスができているのですから・・)
この場合は、送信文字列の入力ができないでしょう。なぜならrecSocket.receiveの受信命令がブロック(待ち)状態になっているからです。
つまり、一つにまとめるには、送信と受信を別のスレッドで動作させる必要があります。
その場合の実現方法は、いくつかありますが、その一つの例でUDPSndTest.javaを
紹介します。
import java.io.*;//BufferedReadered用 import java.net.*;//DatagramSocket、InetAddress用 public class UDPSndTest { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("送信先IPアドレス>"); InetAddress inet = InetAddress.getByName( br.readLine() ); int portNumber = 59152;//ポート番号 DatagramSocket sendSocket = new DatagramSocket();//UDP送信用ソケット Thread thread = new Thread() { public void run(){ try{ UDPRecTest.main(null); } catch(Exception e){ e.printStackTrace(); } } }; thread.start(); for(;;){ System.out.print("送信文字列>"); String msg = br.readLine();//送信メッセージキー入力 if(msg.equals("")) { sendSocket.send(new DatagramPacket(new byte[0], 0, inet, portNumber));//送信 break; } msg = "ここはsから始まる学籍番号に変更" + msg; byte[] buf = msg.getBytes("MS932");//バイト列に変換 DatagramPacket packet; packet = new DatagramPacket(buf, buf.length, inet, portNumber); //IPアドレス、ポート番号も指定 sendSocket.send(packet);//送信 System.out.println(sendSocket.getLocalPort() + "のポートを使って送信します。"); } sendSocket.close();//ソケットを閉じる } }