- サーバ側:ServerSocket クラスを用いる。
- サーバは最初にこの ServerSocketのオブジェクトを生成する。コンストラクタにはポート番号の情報(ここでは10123番とする)が必要。
- ServerSocket の acceptメソッドは、 指定されたポート番号の通信を監視する。プログラムの処理はここで待ち状態に入り、クライアントがこのポートを使って接続してくるまで待つ。
- クライアントからの接続があると、acceptメソッドは Socketクラスのオブジェクトを返り値として返す。サーバにはあらかじめ通信相手のマシン名が予測つかないので、サーバ側のプログラムはSocketのオブジェクトの生成を明示的には記述しない。クライアントが接続してきた時点で初めて通信相手が確定し、そのための Socketが生成される。
- Socketのオブジェクトが得られた後は、複数行のメッセージをクライアントに送信するために、 BufferedWriterのオブジェクトを生成し、ネットワークに送信処理を行う。
- 以下のサンプルでは、サーバからクライアントに対して「一方的な送信」が行われている。このサーバは、クライアントへのメッセージの転送終了後、コネクションを切り、 再び受信モードに戻って次のクライアントからの接続を待つ。
- 10123番ポートが既に使用中、あるいは通信途中にネットワーク障害が発生した場合、例外を発生し停止する(一般には停止せず何とか復旧するようにつとめる)。
サンプルプログラム:サーバ側 MessageServer.java:
import java.net.*; import java.io.*; import java.util.*; /** Socketレベルで通信を行うクラス(サーバ側) */ public class MessageServer { /** ポート番号 */ public static final int PORT = 10123; /** 転送メッセージ */ public static String messages[] = { "********************************", "**** Welcome to My Server! ****", "********************************", }; public static void main( String argv[] ) { try { ServerSocket serverSocket = new ServerSocket( PORT ); while( true ) { Socket socket = serverSocket.accept(); // 受信表示 String remoteName = socket.getInetAddress().getHostName(); Date date = new Date(); String logMessage = remoteName + " connected " + "at " + date.toString(); System.out.println( logMessage ); // メッセージ送信 BufferedWriter bufwriter = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); for( int i=0; i<messages.length; i++ ) { bufwriter.write( messages[i], 0, messages[i].length() ); bufwriter.newLine(); } bufwriter.close(); socket.close(); } } catch( SocketException e ) { System.err.println("Socket Error!"); System.exit(-1); } catch( IOException e ) { System.err.println("IO Error!"); System.exit(-1); } } }
- クライアント側:Socketオブジェクトの生成を行う。これに必要な情報は、 「通信相手」と「ポート番号」の2つである。ここでは、通信相手のマシン名を実行時にコマンドライン引数から指定している。ポート番号は、10123番とする。
- ソケットのオブジェクトが得られた後、Socketクラスは入出力を行うための InputStream およびOutputStream のクラスを内部に持っており、それらを利用する。この例では複数行のテキストの情報をサーバから受け取ることを前提にしているので、BufferedReaderのオブジェクトを生成し、ネットワークからの入力処理を行う。
サンプルプログラム:クライアント側 MessageClient.java:
import java.io.*; import java.net.*; /** Socket通信を行うクラス(クライアント側) */ public class MessageClient { /** 通信に使用するポート番号 */ public static final int PORT = 10123; public static void main( String argv[] ) { try { Socket socket = new Socket( argv[0], PORT ); BufferedReader bufreader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); String line; while( ( line = bufreader.readLine() ) != null ) System.out.println( line ); bufreader.close(); socket.close(); } catch( ArrayIndexOutOfBoundsException e ) { System.err.println("Usage:java MessageClient hostname"); System.exit(-1); } catch( UnknownHostException e ) { System.err.println( "Host not found." ); System.exit(-1); } catch( SocketException e ) { System.err.println("Socket Error!"); System.exit(-1); } catch( IOException e ) { System.err.println("IO Error!"); System.exit(-1); } } }
【実行例】
(1)サーバ側でMessageServer.classを実行(マシン名:localhost、IPアドレス:192.168.0.4)
java -classpath . MessageServer localhost connected at Tue Oct 21 13:51:23 MDT 2003 THINKPAD2 connected at Tue Oct 21 13:52:51 MDT 2003
(2)クライアント側から、MessageClient.classを実行する
java -classpath . MessageClient Usage:java MessageClient hostnamejava -classpath . MessageClient localhost ******************************** **** Welcome to My Server! **** ********************************java -classpath . MessageClient 192.168.0.4 ******************************** **** Welcome to My Server! **** ********************************
2003年10月22日 4:56 更新