next up previous contents
Next: Datagram Up: Network Previous: HTTP

Server

一つのマシン上で複数のサーバ・プロセスが走ることは珍しいことではありません。 それぞれのサーバ・プロセスには、特定の「ポート番号」が割り当てられているので、 サーバ・プロセスは、常に、このポートを監視して、クライアントからの接続要求が ないかをチェックします。 クライアントからの接続要求を感知すると、サーバは、クライアントとの通信用に 新しいSocketのインスタンスを作ります。 このインスタンスから、入出力のストリームを獲得するには、先に見たように、 getInputStream() / getOutputStream() を使います。 通信が終わったら、入出力のストリームを close() し、さらに、通信に使われた ソケットを close() します。 こうして、再び、指定されたポートの監視を続けます。

ServerSocket

ServerSocketクラスのオブジェクトは、サーバ・プロセス内で、指定されたポート番号 へのクライアントの接続要求を監視するために用いられます。

  ServerSocket www = new ServerSocket( 80 ) ;

このようなコードがあれば、それは、このプロセスがサーバ・プロセスであり、 かつ、このプロセスが、ポート番号 80で、クライアントからの接続要求を監視する ということを意味しています。

クライアント側で用いられた、Socket オブジェクトの生成では、ポート番号の他に、 接続するマシン名が必要でしたが、サーバ側の、ServerSocket オブジェクトの生成 では、ポート番号だけで十分ということになります。

accept()

accept() メソッドは、ServerSocketのオブジェクトに作用して、通信用の Socketインスタンスを返します。accept()メソッドは、クライアントからの接続要求 があるまで、ブロックします。

accept()で、いったんSocketクラスのインスタンスが手にはいれば、それからは、 クライアント側の処理と全く同様に、ストリームを獲得し、それに対して入出力の 処理を行います。

  ServerSocket www = new ServerSocket( 80 ) ;
  Socket s = www.accept();
  DataInputStream in = new DataInputStream( s.getInputStream() );
  PrintStream  out = new PrintStream( s.getOutputStream() );

複数の接続要求

通常、サーバ・プロセスは、特定のポートに対応したServerSocketを生成した後は、 無限ループに入ります。こうして繰り返しクライアントからの要求に応えることが 出来るようになるのですが、この処理には大きな問題があります。 大きな画像データの転送の依頼のように、クライアントから要求された処理に時間が かかる場合を考えてみましょう。こうした時、たとえ、cpuには十分な余力が残って いるとしても、他のクライアントからの処理は、時間のかかる処理が完全に終わるまで 待たされることになります。

こうした時には、次のようにします。 まず、クライアントとの接続が保障された Socket オブジェクトが与えられた時の サーバの処理を、Thread を継承する、別のクラスとして作成します。この時、 Socket オブジェクトを引数に取るようなコンストラクタを作っておきます。いま、 このクラスを ServerThread としましょう。

  ServerSocket www = new ServerSocket( 80 ) ;
  while( true ){
     Socket s = www.accept();
     ServerThread st = new ServerThread(s).start();
  }



maruyama@wakhok.ac.jp