1. 程式人生 > >多執行緒-實現一個簡單人Echo伺服器

多執行緒-實現一個簡單人Echo伺服器

 

實現一個簡單的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等待,如果客戶端傳送資料時非常慢,這時服務端一直將等待客戶端傳送資料完畢,這樣以來如果每個請求都這樣,將拖慢伺服器處理處理,伺服器的併發數將大大下降,在極端情況下服務端程式將會拖垮!