前回作ったサーバーは接続してきたクライアントにメッセージを送るというものでした。
今回はメッセージを受け付けるサーバーを作ってみます。通信内容をコマンドライン引数として入れることで人同士の通信に使えます。
送られてきたメッセージを表示するだけというサーバーです。このサーバーも 10001 ポートで待ちます。
/** 受けたメッセージを表示するだけのサーバー */ import java.net.*; import java.io.*; public class Server02 { public static void main( String[] args ) { int PORT = 10001; try { ServerSocket mysvsoc = new ServerSocket( PORT ); while( true ) { //クライアントが接続してくるまで待ち続ける System.out.println( "waiting..." ); Socket mysoc = mysvsoc.accept(); //接続してきたホストの名前を表示 String remotehost = mysoc.getInetAddress().getHostName(); System.out.println(remotehost + ":"); // メッセージを受信 InputStreamReader in = new InputStreamReader(mysoc.getInputStream()); BufferedReader inb = new BufferedReader(in); String line; while( ( line = inb.readLine() ) != null ){ System.out.println( line ); } System.out.println(); inb.close(); in.close(); mysoc.close(); } } catch( SocketException e ) { System.err.println("Socket Error"); } catch( IOException e ) { System.err.println("IO Error"); } catch( java.lang.Exception e ){ System.out.println(e.toString()); } } }
実行すると次のようになって接続を待ちます
$ java Server02 waiting...
まだサーバーしかなく接続してくるクライアントはありませんのでいつまでもこのままです。しかし,前回のClient01ではうまく通信できません。
Client02を作り、それで接続します。接続があると次のように相手のホスト名とメッセージを表示し,また待機状態に戻ります。
$ java Server02 waiting... vineXX: Konnichihwa hoge desu. waiting...
サーバーを停止するには ctrl+c (コントロールキーを押しながらc)で止めます。
これはしばらく止めずにおいて,端末(コンソール)を起動してクライアントを作りましょう。もう一度[アプリケーション]-[プログラミング]-[java]を選ぶのが一番簡単です。
今回も 1001 を使いますが、今度は送信をするクライアントです。
/** メッセージを送りつけるクライアント */
import java.io.*;
import java.net.*;
public class Client02 {
public static void main( String[] args ) {
/** 通信に使用するポート番号 */
int PORT = 10001;
try {
Socket mysoc = new Socket( args[0], PORT );
OutputStreamWriter out = new OutputStreamWriter(mysoc.getOutputStream());
BufferedWriter outb = new BufferedWriter(out);
for( int i=1; i < args.length; i++ ) {
System.out.println( args[i] );
outb.write( args[i], 0, args[i].length() );
outb.newLine();
outb.flush();
}
outb.close();
out.close();
mysoc.close();
}
catch( ArrayIndexOutOfBoundsException e ) {
System.err.println("Usage:java Client02 hostname message");
}
catch( UnknownHostException e ) {
System.err.println( "Host not found" );
}
catch( SocketException e ) {
System.err.println("Socket Error");
}
catch( IOException e ) {
System.err.println("IO Error");
}
}
}
実行する時には、
$ java Client02 vineXX Konnichihwa hoge desu.
というように引数として通信したいホストの名前と、通信内容を引数として入れます。まずは自分の使っているコンピュータのホスト名でテストしましょう。
実行すると次のようにサーバーに送ったメッセージを自分の所にも表示します。(プログラムでわざわざ表示するようにしているからです。しないようにもできます)
$ java Client02 vineXX Konnichihwa hoge desu. Konnichihwa hoge desu. $
引数はスペースで区切られて、args[0], args[1], args[2], ... に代入されますから、スペースは改行になってでます。必要に応じてクォーテーションでくくるとそれを防ぐことができます。
ここで大事なのが、outb.flush(); です。BufferedWriter はバッファにデータをためていっぱいなったり、クローズされる時にまとめて送信しようとします。もちろんその方が仕事の効率はいいのですが、今回のような例ではバッファに書き込まれるが実際には送信されないということが起こります。これを今までにたまっている分を送信させるメソッドが outb.flush(); なのです。
前回のプログラムでは、送信後すぐにクローズされたのでこの問題は起こりませんでした。