傳統的阻塞IO,不過服務端採用線程池,一個客戶端到達後起一個線程進行處理。在本實例中,服務端採用Executors管理線程池。廢話少說,直接上代碼:
服務端Server.java代碼:
package com.test.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(9527), 10);
final AtomicInteger count = new AtomicInteger(0);
ExecutorService pool = Executors.newCachedThreadPool(new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r, "ThreadPool-new-" + count.incrementAndGet());
}
});
while(true) {
try {
final Socket clientSocket = serverSocket.accept();
pool.execute(new Runnable() {
public void run() {
String client = clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort();
System.out.println(client + " received!");
System.out.println(Thread.currentThread().getName() + " handle " + client);
try {
clientSocket.setTcpNoDelay(true);
clientSocket.setReuseAddress(true);
BufferedReader bufReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
String line = bufReader.readLine();
System.out.println(client + " say:" + line);
writer.println("received '" + line + "'");
writer.flush();
Thread.sleep(10000);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
編譯:javac -d ./ Server.java
運行:java com/test/socket/Server
客戶單Client.java代碼:
package com.test.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9527);
socket.setTcpNoDelay(true);
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("hello world");
out.flush(); //必須flush,服務端無法收到消息
String line = reader.readLine();
System.out.println("server say : " + line);
socket.close();
}
}
編譯、運行同Server端操作。
程序運行後可以快速的運行Client多次,查看服務器端的輸出結果。(注意客戶單的端口號是由操作系統隨機分配的,根據不同的端口號可以判斷是不同的客戶端請求)
運行結果如下: