Java - ソケットによるネットワーク通信


■ページ目次

Top

■ソケット

■ソケットの種類
■クライアント / サーバー
■接続
Top

■ストリーム・ソケット(TCP)を使用するケット通信

Top
■ServerSocket クラスとSocket クラス
■ソケットの獲得
■入出力ストリームの獲得
Top
■例題
  1. クライアント"SocketClient01.java" からの要求により、サーバー"SocketServer01.java"が日時を返します。
    サーバーのコマンドライン引数は、ポート番号、
    クライアントのコマンドライン引数は、ホスト名(IPアドレス)、ポート番号 です。

    □サーバー "SocketServer01.java"

    1. import java.io.*;
    2. import java.net.*;
    3. import java.util.*;
    4. public class SocketServer01 {
    5. public static void main(String[] args) {
    6. try {
    7. int port = Integer.parseInt(args[0]);
    8. ServerSocket ss = new ServerSocket(port);
    9. System.out.println("Running...");
    10. while (true) {
    11. Date date = new Date();
    12. Socket s = ss.accept();
    13. System.out.println(s + " was accepted at " + date);
    14. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
    15. dos.writeUTF(date.toString());
    16. dos.close();
    17. s.close();
    18. }
    19. } catch (Exception e) {
    20. System.out.println("Exception: " + e);
    21. }
    22. }
    23. }

    □ 実行結果

    $ java SocketServer01 12345
    Running...
    Socket[addr=/127.0.0.1,port=4581,localport=12345] was accepted at Tue Jun 29 10:15:17 JST 2004
    

    □クライアント "SocketClient01.java"

    1. import java.io.*;
    2. import java.net.*;
    3. public class SocketClient01 {
    4. public static void main(String[] args) {
    5. try {
    6. String server = args[0];
    7. int port = Integer.parseInt(args[1]);
    8. Socket s = new Socket(server, port);
    9. DataInputStream dis = new DataInputStream(s.getInputStream());
    10. System.out.println("Message from server: " + dis.readUTF());
    11. dis.close();
    12. s.close();
    13. } catch (Exception e) {
    14. System.out.println("Exception: " + e);
    15. }
    16. }
    17. }

    □ 実行結果

    $ java SocketClient01 localhost 12345
    Message from server: Tue Jun 29 10:15:23 JST 2004
    
Top
■実習
  1. 例題のサーバー"SocketServer01.java"を改良して、要求された数(訪問者数)をクライアントに戻すサーバー"SocketServer02.java"にしてください。
    クライアントの変更はありません。

    □サーバー "SocketServer02.java"

    □ 実行結果

    $ java SocketServer02 12345
    Running...
    Socket[addr=/127.0.0.1,port=4581,localport=12345] was accepted at Tue Jun 29 10:15:17 JST 2004
    
    □クライアント 
    "SocketClient01.java"

    □ 実行結果

    $ java SocketClient01 localhost 12345
    Message from server: Tue Jun 29 10:15:23 JST 2004
    
  2. 上記サーバー"SocketServer02.java"を改良して、サーバーがシャットダウンした場合でも、継続して、要求された数(訪問者数)をクライアントに戻すサーバー"SocketServer03.java"にしてください。
    これには、訪問者数をテキスト形式のファイルに保存することで実現します。
    クライアントの変更はありません。

    □サーバー "SocketServer03.java"

    □ 実行結果

    $ java SocketServer02 12345
    Running...
    Socket[addr=/127.0.0.1,port=4581,localport=12345] was accepted at Tue Jun 29 10:15:17 JST 2004
    
    □クライアント 
    "SocketClient01.java"

    □ 実行結果

    $ java SocketClient01 localhost 12345
    Message from server: Tue Jun 29 10:15:23 JST 2004
    
Top

■商品管理システム

  1. いままでのTestProductをクライアントとし、Product関連をサーバーとして、クライアント・サーバー型のアプリケーションを作成します。 通信はTCPを使います。

    □クライアント 
    "TestProduct.java"
    1. // 1603
    2. // package application;
    3. import java.io.*;
    4. import java.net.*;
    5. // 商品クラスをテストするクラスです。
    6. public class TestProduct {
    7. public static void main(String[] args) throws Exception {
    8. final int SERVER_PORT = 54321;
    9. final String serverName = args[0];
    10. Socket sock = null;
    11. BufferedReader br = null;
    12. try {
    13. br = new BufferedReader(new InputStreamReader(System.in));
    14. String str = null;
    15. while ((str = br.readLine()) != null && !str.toUpperCase().equals("X")) {
    16. // クライアントと対話処理するストリーム、ソケットを生成
    17. sock = new Socket(serverName, SERVER_PORT);
    18. DataInputStream dis =
    19. new DataInputStream(sock.getInputStream());
    20. DataOutputStream dos =
    21. new DataOutputStream(sock.getOutputStream());
    22. dos.writeUTF(str);
    23. System.out.println("商品コード " + str + " の商品は " + dis.readUTF() + " です。");
    24. // ストリーム、ソケットをクローズ
    25. dos.close();
    26. dis.close();
    27. sock.close();
    28. }
    29. } catch (IOException e) {
    30. e.printStackTrace();
    31. } finally {
    32. try {
    33. br.close();
    34. sock.close();
    35. } catch (IOException e) {
    36. e.printStackTrace();
    37. }
    38. }
    39. }
    40. }
    • 実行結果(クライアント)
    $ java TestProduct localhost
    A001
    商品コード A001 の商品は [A001, パソコン, 188000] です。
    B001
    商品コード B001 の商品は [Not Found] です。
    C001
    商品コード C001 の商品は [C001, DVD-ROM, 9200] です。
    
    □サーバー 
    "ProductServer.java"
    1. // 1603
    2. // package server;
    3. // import product.*;
    4. import java.util.*;
    5. import java.net.*;
    6. import java.io.*;
    7. // 商品サーバーです。
    8. public class ProductServer {
    9. public static void main(String[] args) throws Exception {
    10. final int SERVER_PORT = 54321;
    11. TreeMap p = new TreeMap();
    12. SetProduct s = new SetProduct("SA01", "パソコン・セット", 10, p);
    13. System.out.println("セット商品のインスタンスを生成しました。 s = " + s);
    14. System.out.println();
    15. AdminProduct ap = new AdminProduct();
    16. ap.read(s, args[0]);
    17. System.out.println("セット商品のデータを設定しました。 s = " + s);
    18. // サーバ用ソケットの作成
    19. ServerSocket serversock = new ServerSocket(SERVER_PORT);
    20. // 非同期制御データ・オブジェクトの作成
    21. while (true) {
    22. // クライアントからの接続要求待ち
    23. Socket sock = serversock.accept();
    24. System.out.println("socket = " + sock);
    25. // クライアントと対話処理するストリーム、ソケットを生成
    26. DataInputStream dis =
    27. new DataInputStream(sock.getInputStream());
    28. DataOutputStream dos =
    29. new DataOutputStream(sock.getOutputStream());
    30. String code = dis.readUTF();
    31. String result = s.query(code);
    32. System.out.println(" [" + code + " = " + result + "]");
    33. dos.writeUTF(result);
    34. // ストリーム、ソケットをクローズ
    35. dos.close();
    36. dis.close();
    37. sock.close();
    38. }
    39. }
    40. }
    • 実行結果(サーバー)
    $ java ProductServer products.txt
    セット商品のインスタンスを生成しました。 s = [SA01, パソコン・セット, 10, 0]
    
    セット商品のデータを設定しました。 s = [SA01, パソコン・セット, 10, 207360]
    socket = Socket[addr=/127.0.0.1,port=4104,localport=54321]
      [A001 = [A001, パソコン, 188000]]
    socket = Socket[addr=/127.0.0.1,port=4105,localport=54321]
      [B001 = [Not Found]]
    socket = Socket[addr=/127.0.0.1,port=4106,localport=54321]
      [C001 = [C001, DVD-ROM, 9200]]
    
Top

■データグラム・ソケット(UDP)を使用するケット通信

Top
■DatagramSocket クラス
Top
■DatagramPacket クラス
Top
■InetAddress クラス
Top
■例題
  1. 送信側アプリケーション"UdpSend01.java"が送ったメッセージを、受信側アプリケーション"UdpReceive01.java" が受取り、表示します。
    送信側のコマンドライン引数は、受信側のホスト名(IPアドレス)、メッセージ です。

    □受信側 "UdpReceive01.java"

    1. import java.net.*;
    2. public class UdpReceive01 {
    3. //データの最大長
    4. private static int BUFFER_SIZE = 256;
    5. //ポート番号
    6. static int port = 10000;
    7. public static void main(String[] args) {
    8. try {
    9. //データグラム・ソケット・オブジェクト生成
    10. DatagramSocket ds = new DatagramSocket(port);
    11. byte[] data = new byte[BUFFER_SIZE];
    12. System.out.println("Waiting...");
    13. while (true) {
    14. //データグラム・パケット・オブジェクト生成
    15. DatagramPacket dp = new DatagramPacket(data, BUFFER_SIZE);
    16. //データを受け取る
    17. ds.receive(dp);
    18. data = dp.getData();
    19. //データ長の取得
    20. int length = dp.getLength();
    21. //Stringオブジェクトの生成
    22. String str = new String(data, 0, length);
    23. System.out.println(str);
    24. }
    25. } catch (Exception e) {
    26. System.err.println("Exception : " + e);
    27. }
    28. }
    29. }

    □ 実行結果

    $ java UdpReceive01
    Waiting...
    Hello
    
    (*) CTRL+C で停止してください。

    □送信側 "UdpSend01.java"

    1. import java.net.*;
    2. public class UdpSend01 {
    3. public static void main(String[] args) {
    4. try {
    5. //サーバーを取得する
    6. InetAddress host = InetAddress.getByName(args[0]);
    7. //ポート番号
    8. int port = 10000;
    9. //メッセージ
    10. String message = args[1];
    11. //データグラム・ソケット作成
    12. DatagramSocket ds = new DatagramSocket();
    13. byte[] data = message.getBytes();
    14. //データグラム・パケット作成
    15. DatagramPacket dp = new DatagramPacket(data, data.length, host, port);
    16. ds.send(dp);
    17. System.out.println("Send done");
    18. } catch (Exception e) {
    19. System.err.println("Exception : " + e);
    20. }
    21. }
    22. }

    □ 実行結果

    $ java UdpSend01 localhost Hello
    Send done
    
Top
■実習
Top

■通信時のエンコーディング指定

Top
■例題
Top
■実習
Top

inserted by FC2 system