上篇文章介绍了Socket和ServerSocket简单使用和源码,服务器端会对每个客户端请求创建一个线程,为使服务器端能同时处理多个客户端请求,可以采用多线程的方式。本文仅对实例进行简单记录,如下。
服务器端
importjava.io.IOException;.ServerSocket;.Socket;public classMultiJabberServer {static final int PORT = 8080;public static void main(String[] args) throwsIOException{
ServerSocket serverSocket= newServerSocket(PORT);
System.out.println("Server Started");try{while(true) {
Socket socket=serverSocket.accept();try{newServeOneJabber(socket);
}catch(IOException e) {//If it fails, close the socket,//otherwise the thread will close it:
socket.close();
}
}
}finally{
serverSocket.close();
}
}
}
while循环获取连接,并构造ServerOneJabber,启动线程处理客户端交互。
importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.OutputStreamWriter;importjava.io.PrintWriter;.Socket;public class ServeOneJabber extendsThread{privateSocket socket;privateBufferedReader in;privatePrintWriter out;public ServeOneJabber(Socket socket) throwsIOException{this.socket =socket;
in= new BufferedReader(newInputStreamReader(socket.getInputStream()));
out= new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
start();
}public voidrun() {try{while (true) {
String str=in.readLine();if ("END".equals(str)) {break;
}
System.out.println("Echoing: " +str);
out.println("Got: " +str);
}
System.out.println(socket+ ", seesion closing....");
}catch(IOException e) {
System.out.println(e.getMessage());
}finally{try{
socket.close();
}catch(Exception e2) {
System.out.println("Socket not closed");
}
}
}
}
原理与上篇文章一样,获取输入输出流,对请求信息进行处理和响应。
客户端
importjava.io.IOException;.InetAddress;public classMultiJabberClient {static final int MAX_THREADS = 40;public static void main(String[] args) throwsIOException, InterruptedException{
InetAddress addr= InetAddress.getByName(null);for(int i = 0; i < MAX_THREADS; i++) {newJabberClientThread(addr);
Thread.sleep(100);
}//while(true) {//if(JabberClientThread.threadCount() < MAX_THREADS) {//new JabberClientThread(addr);//}//Thread.sleep(100);//}
}
}
构造线程JabberClientThread,构建Socket,与服务器端连接。
importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.OutputStreamWriter;importjava.io.PrintWriter;.InetAddress;.Socket;public class JabberClientThread extendsThread{privateSocket socket;privateBufferedReader in;privatePrintWriter out;private static int counter = 0;private int id = counter++;private static int threadCount = 0;public static intthreadCount() {returnthreadCount;
}publicJabberClientThread(InetAddress addr){
System.out.println("Making client " +id);
threadCount++;try{
socket= newSocket(addr, MultiJabberServer.PORT);
}catch(IOException e) {//If the creation of the socket fails,//nothing needs to be cleaned up.
System.out.println("Socket failed");return;
}try{
in= new BufferedReader(newInputStreamReader(socket.getInputStream()));
out= new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
start();
}catch(IOException e) {//The socket should be closed on any//failures other than the socket//constructor:
try{
socket.close();
}catch(IOException e2) {
System.err.println("Socket not closed");
}
}
}public voidrun() {try{for(int i = 0; i < 5; i++) {
out.println("Client " + id + ":" +i);
String str=in.readLine();
System.out.println(str);
}
out.println("END");
}catch(IOException e) {
System.err.println("IO Exception");
}finally{try{
socket.close();
}catch(IOException e2) {
System.err.println("Socket not closed");
}
threadCount--;
}
}
}
其中包含成员属性id和threadCount,每创建一个线程,id递增(采用类成员控制);threadCount作为线程数量的记录,线程创建时加一,结束时减一。
运行结果如下:
服务器端:
Server Started
Echoing: Client0:0Echoing: Client0:1Echoing: Client0:2Echoing: Client0:3Echoing: Client0:4Socket[addr=/127.0.0.1,port=42998,localport=8080], seesion closing....
Echoing: Client1:0Echoing: Client1:1Echoing: Client1:2Echoing: Client1:3Echoing: Client1:4Socket[addr=/127.0.0.1,port=43000,localport=8080], seesion closing....
......
Echoing: Client39:0Echoing: Client39:1Echoing: Client39:2Echoing: Client39:3Echoing: Client39:4Socket[addr=/127.0.0.1,port=43076,localport=8080], seesion closing....
客户端:
Making client 0Got: Client0:0Got: Client0:1Got: Client0:2Got: Client0:3Got: Client0:4Making client1Got: Client1:0Got: Client1:1Got: Client1:2Got: Client1:3Got: Client1:4.....
Making client39Got: Client39:0Got: Client39:1Got: Client39:2Got: Client39:3Got: Client39:4