java socket多线程阻塞IO

来源:互联网 发布:淘宝超过时间不能评价 编辑:程序博客网 时间:2024/05/16 05:00

传统的阻塞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多次,查看服务器端的输出结果。(注意客户单的端口号是由操作系统随机分配的,根据不同的端口号可以判断是不同的客户端请求)

运行结果如下:


1 0
原创粉丝点击