25. DatagramSocket

UDP を使った通信プログラムについて説明します。

(1) UDP を使った通信プログラム

 Java ではネットワークを介した通信プログラムをもう1つ紹介しておきましょう。前回は TCP を使った通信法を紹介しましたが、今回はUDPを使った通信です。今回も java.net パッケージのクラスを使います。

 UDP は手紙のような通信方法です。前回の TCP とは違い、相手に接続したことを確認することなくデータを送ります。ポストに手紙を入れたらあとは勝手に相手に届きますよね。

 UDP を使った通信では相手に接続してから通信をはじめるわけではないので、サーバとクライアントという明確な分け方はできません。ですが、説明の都合上はじめに起動されているプログラムの方をサーバと呼ぶことにします。

 今回の UDP を使った通信でも相手を特定するのにホスト名(IPアドレス)とポート番号を知っている必要があります。

(2) データを送信する場合

 データを送信するときは java.net パッケージの DatagramSocket クラスを使い、DatagramSocket を作成します。このとき、適当なポート番号(ただし1024より大きい値)を指定します。
DatagramSocket(int port) throws SocketException

 データを送信する場合は、DatagramPacket というデータを入れる箱を用意します。この中に送信するデータ、データの長さ、相手のIPアドレス、ポート番号を入れます。送信するデータはバイト列にしなければならないので注意してください。

DatagramPacket(byte[ ] buf, int length, InetAddress address, int port)

 これで準備はできました。あとは送信するだけです。送信する場合は、DatagramSocket クラスの send( ) を使い作成した DatagramPacket を送信します。

send(DatagramPacket packet)

InetAddress クラスはこの章の後半で紹介するよ。


(3) データを受信する場合

 データを受信するときも DatagramSocket を作成します。このとき、適当なポート番号(ただし1024より大きい値)を指定します。
DatagramSocket(int port) throws SocketException

 データを受信する場合は、受信用の DatagramPacket を用意します。この中に受信するデータ、データの長さを入れます。

DatagramPacket(byte[ ] buf, int length)

 この DatagramPacket にデータを受信するには DatagramSocket クラスの recieve( ) を使います。

recieve(DatagramPacket packet)


(4) IP アドレスを管理するクラス 〜InetAddress〜

 DatagramPacket 作成の際に InetAddress というクラスがでてきました。これは java.net パッケージのクラスで IPアドレスを管理します。

 たとえばこのクラスの static メソッドを使ってホスト名から IP アドレスを取得することができます。
static InetAddress getByName(String hostName)



(5) プログラムの例

 まずはサーバー側のプログラムです。こちらはデータを受信し、受信したデータを表示します。DatagramPacket からデータを取り出すには getData( ) というメソッドを使います。

  UDPServer.java

import java.net.*;
import java.io.*;

class UDPServer {
    public static void main(String args[]) {
        System.out.println("Ready!");
        try {
            DatagramSocket ss = new DatagramSocket(5000);
            byte recvData[] = new byte[1024];  // 受信するデータ
            DatagramPacket packet = 
                     new DatagramPacket(recvData, recvData.length);
            
            // データを受信する(受信するまで待つ)
            ss.receive(packet);

            // DatagramPacketからデータを取りだし文字列を再構築
            String recvStr = new String( packet.getData() );
            System.out.println("受信したデータ : "+recvStr);

        } catch (Exception e) {
            System.out.println("Server : IOError");
            e.printStackTrace();
        }
    }
}

 次にクライアント側のプログラムです。このデータを送信する場合はバイト列にしなければいけません。今回は文字列を送信するので、String クラスの getBytes( ) メソッドを使ってバイト列に分解します。

  UDPClient.java

import java.net.*;
import java.io.*;

class UDPClient {
    public static void main(String args[]) {
        if ( args.length!=2 ) {
     System.out.println("使い方:java UDPClient <hostName> <sendData>");
            System.exit(0);
        }
        try {
            DatagramSocket ss = new DatagramSocket(6000);
            String sendData = args[1];                  // 送信データ
            int port = 5000;                            // 送信先ポート
                                                        // 送信先アドレス
            InetAddress sendAddr = InetAddress.getByName(args[0]);

            DatagramPacket packet = new DatagramPacket(
                                            sendData.getBytes(),
                                            sendData.getBytes().length,
                                            sendAddr,
                                            port);
            ss.send(packet);
        } catch (Exception e) {
            System.out.println("Server : IOError");
            e.printStackTrace();
        }
    }
}

 実行する場合は、サーバープログラムを先に実行します。

C:\java_test>java UDPServer
Ready!

 つぎにもう1つ立ち上げた MS-DOS プロンプトでクライアントのプログラムを実行します。パラメータの1つ目にはホスト名を指定します。今回は自分のコンピュータを指定するので 127.0.0.1 を指定してください。2つ目のパラメータには文字列を指定します。

C:\java_test>java UDPClient 127.0.0.1 データ送信のテスト


 実行結果は以下のようになります。

 サーバ側の結果

C:\java_test>java UDPServer
Ready!
受信したデータ : データ送信のテスト


前の章(24.Socketを使った通信)