多執行緒-實現一個簡單人Echo伺服器
阿新 • • 發佈:2019-01-05
實現一個簡單的Echo伺服器
伺服器端監聽服務端的到來,當監聽到客戶端到來之後,將建立一個執行緒去處理客戶端Socket
伺服器端:
public class MultiThreadEchoServer { private static ExecutorService es = Executors.newCachedThreadPool(); /** * 處理客戶端socket */ static class ClientHandler implements Runnable { private Socket clientSocket; public ClientHandler(Socket clientSocket) { this.clientSocket = clientSocket; } @Override public void run() { try ( InputStream in = clientSocket.getInputStream(); OutputStream out = clientSocket.getOutputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); PrintWriter pw = new PrintWriter(out, true); ) { long start = System.currentTimeMillis(); String line = null; while ((line = br.readLine()) != null) { pw.println(line); } long end = System.currentTimeMillis(); System.out.println("處理耗時:" + (end - start) + "ms"); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8000); while (true) { // 監聽客戶端的到來 Socket clientSocket = serverSocket.accept(); // 分配一個執行緒去處理客戶端Socket es.execute(new ClientHandler(clientSocket)); } } catch (IOException e) { e.printStackTrace(); } } }
客戶端:
public class Client { public static void main(String[] args) throws IOException { Socket client = new Socket(); SocketAddress addr = new InetSocketAddress("localhost", 8000); client.connect(addr); try ( OutputStream out = client.getOutputStream(); PrintWriter pw = new PrintWriter(out, true); InputStream in = client.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); ) { // 向伺服器傳送資料 pw.println("hello"); pw.flush(); // 從伺服器讀資料 System.out.println("伺服器響應:" + br.readLine()); } } }
相比單執行緒中處理Socket,它更好的使用多核CPU,可以儘量多的支援客戶端數量,但是它的弱點在於,讓CPU進行IO等待,如果客戶端傳送資料時非常慢,這時服務端一直將等待客戶端傳送資料完畢,這樣以來如果每個請求都這樣,將拖慢伺服器處理處理,伺服器的併發數將大大下降,在極端情況下服務端程式將會拖垮!