Socketラーニングノート(二)Socketのマルチクライアントサポートクライアント/serverプログラム

4228 ワード

前章のClient/Serverプログラムでは、サーバと1人のお客様の会話しか実現できません.実際のアプリケーションでは、サーバ上で永続的なプログラムを実行することが多く、他の複数のクライアントからの要求を受信し、対応するサービスを提供することができます.サーバ側で複数のクライアントにサービスを提供する機能を実現するためには,上記のプログラムを改造し,マルチスレッドを用いてマルチクライアントメカニズムを実現する必要がある.サーバは常に指定されたポートでクライアント要求があるかどうかを傍受し、クライアント要求が傍受されると、サーバは特定のサービススレッドを起動してクライアントの要求を鳴らすが、サーバ自体はスレッドを起動した後、すぐに傍受状態に入り、次のクライアントの到着を待つ.
[b](一)各リクエストが完了するタスクの具体的な内容は以下の通りである[/b]

package com.mytest.socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class SocketTask implements Runnable{

private Socket socket;
private String name;

public SocketTask(Socket socket,String name)
{
this.socket=socket;
this.name=name;
System.out.println(name+" .....");
}

@Override
public void run() {

InputStream in = null;
try {
in = socket.getInputStream();
byte []buff=new byte[100];
StringBuffer sb=new StringBuffer();
//
while(in.read(buff)!=-1)
{
String str= new String(buff,"UTF-8").trim();
sb.append(str);
}
in.close();
System.out.println(" :"+sb.toString());
System.out.println(name+" ");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{

try {
if(in!=null)
{
in.close();
}
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}




}

}



[b](二)サービス側が要求を受信した後に完了する動作.具体的なコードは以下の通りである.

package com.mytest.socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SocketSevice {

//
private int port;

private ServerSocket serverSocket;

//
private static int maxCount=3;

//
private int index=0;

private static final SocketSevice socketSevice=new SocketSevice();

     //
private ExecutorService threadPool=Executors.newFixedThreadPool(maxCount);

private SocketSevice(){}

public static SocketSevice getInstance()
{

return socketSevice;
}

public void listening(int port) throws IOException
{
this.port=port;
serverSocket=new ServerSocket(port);

// accept() , Socket ,
while(true){
Socket socket=serverSocket.accept();
SocketTask task=new SocketTask(socket," "+index);
threadPool.execute(task);
index++;


}


}

public static void main(String[] args)
{
SocketSevice s=SocketSevice.getInstance();
try {
s.listening(1099);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


public int getPort() {
return port;
}

public void setPort(int port) {
this.port = port;
}



}



[b](3)複数のクライアントからサーバへの要求をシミュレートし,前章のSocketClientクラスのmainメソッドを修正する.コードは以下のようになる[/b]

public static void main(String[] args) {
// TODO Auto-generated method stub

try {
for(int i=0;i<5;i++){
SocketClient client=new SocketClient("127.0.0.1",1099);
client.writeString(" "+i);
client.close();

}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}


サービス・エンド・コード(SocketServer)を実行してから、クライアント・コード(SocketClient)を実行します.効果は次のとおりです.
[img]http://dl2.iteye.com/upload/attachment/0117/0042/24be3fa6-4bea-3dd3-8c8c-69361196da00.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/0040/2480c9ea-285a-304e-903c-3715820ca2bb.png[/img]