java socket多線程阻塞IO

傳統的阻塞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多次,查看服務器端的輸出結果。(注意客戶單的端口號是由操作系統隨機分配的,根據不同的端口號可以判斷是不同的客戶端請求)

運行結果如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章