今回は、JavaのServerSocketを使って簡単なサーバーを作ってみて、サーバープログラム開発の基本を確認してみましょう。サーバーの機能としては、接続してきたクライアントに文字列のメッセージを出し、いくつかコマンドを受け付け処理する、というものです。ただし、複数の接続や効率などは一切考えず、サーバープログラムの基本的な構造のみを作ってます。 サーバーの構造と実装Javaに用意されているServerSocketクラスのコンストラクタでは、サーバーが使用するポートを指定できます。ここでポートを指定しておくとServerSocketは指定されたポートを監視して接続を待ち、accept()で接続してきたクライアントとの通信に使用するソケットを取得することができるようになります。
という構造で作ってみます。この構造は、ループの制御用にboolean型変数go(ループ1)とlogon(ループ2)を用意し、 サーバーソケット作成 while(go) { クライアントからの接続受け入れ while(logon) { クライアントとの通信処理 } 接続解除 } 終了処理(サーバーソケットクローズ) という形で処理すれば良いでしょう。 まず、サーバーソケットssの作成は、今回使用するポート7777を引数にServerSocketのコンストラクタを呼び出します。 ss=new ServerSocket(7777); サーバーソケットができたら、サーバー処理本体のループに入ります。ループでは、最初にaccept()でクライアントからの接続を待ち、接続されたらソケットを取得して入出力用のストリームを作成しましょう。なお、入力ストリームはクライアントから取得した文字列をJavaの2バイト文字列に変換するためInputStreamReaderを使用しています。 while (go) { // サーバーループ sc=ss.accept(); // ストリーム取得 os=sc.getOutputStream(); isr=new InputStreamReader(sc.getInputStream()); 続いて、今取得したosに接続メッセージを出しましょう。 String mes="Test Server!\r\n"; os.write(mes.getBytes()); これで、接続時に行う処理は終了です。次に、クライアントからコマンド入力を受けそのコマンドを処理するループに入ります。今回は、改行までの1行を一つのコマンドとして認識し、以下のコマンドを定義しました。
boolean logon=true; while (logon) { // コマンド処理ループ boolean bRead=true; StringBuffer sb=new StringBuffer(); while (bRead) { // 改行までの文字列入力取得 c=isr.read(); if (c=='\r' || c=='\n') // 改行文字ならループ終了 bRead=false; else // 読み込んだ文字を文字バッファに追加 sb.append((char)c); } line=sb.toString(); // 入力されたコマンド if (line.length()>0) { // コマンド処理 // 入力されたコマンドを送信し返す mes="Command:"+line+"\r\n"; os.write(mes.getBytes()); if (line.equals("host")) { // hostコマンド mes=ss.toString()+"\r\n"; os.write(mes.getBytes()); } if (line.equals("local")) { // localコマンド mes=sc.toString()+"\r\n"; os.write(mes.getBytes()); } if (line.equals("logout")) // logoutコマンド logon=false; if (line.equals("exit")) { // exitコマンド sc.close(); logon=false; go=false; } } } sc.close(); ループ内では改行が来るまで入力文字列を加えて行き、改行が来たらそれまでに受け取った文字列をコマンドとして処理しています。接続やサーバー自体の終了は、ループ制御変数go/logonで行うようにしました。 logoutコマンドでlogonがfalseになると、コマンド処理ループから抜けてクライアントとのソケットを閉じます。そして、またサーバーループ先頭のaccept()に戻って次の接続を待ちます。 プログラム今回のプログラムはコンソールJavaアプリケーションです。javacでコンパイルして実行すると、サーバーが立ち上がります。次に、サーバーが動いているマシンに対しtelnetでポート7777に接続してください。同じマシンから接続する場合は telnet localhost 7777 とします。 接続したら、コマンドを受け付ける状態になるのでhost/local/logout/exitコマンドを実行してみましょう。logoutするとサーバーとの接続が切れますので、そのまま再度接続してサーバーがクライアントと接続・切断を繰り返す様子を確認してみてください。さらに、すでにクライアントが接続している状態で新たな接続を要求するとどうなるか、その接続しているクライアントがlogoutするとどうなるか、見てみましょう。 サーバーを終了するには、クライアントからexitコマンドを送ります。 今回のサーバープログラムでサーバー側プログラム開発の流れをつかめたら、独自のプロトコルを実装してみてください。 |