欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TCP实现服务器与客户端的连接(多线程)

程序员文章站 2022-06-06 12:09:56
...

上一篇博客中,我们用TCP实现了服务器与客户端的连接。但是有一个问题,即一个客户端在和服务器交互时,其他客户端无法连接,为解决这一问题,我们将服务器端改造为线程池的版本。

(1)在主线程中服务器只负责接待客户端的请求。接收到客户端的请求后,我们把请求提交至线程池是工作队列中。

public static void main(String[] args) throws IOException {
    //创建线程池,大小为10
	ExecutorService pool = Executors.newFixedThreadPool (10);
    //服务器起一个端口
    ServerSocket serverSocket = new ServerSocket (8080);
    while(true){
        Socket socket = serverSocket.accept ();//接收客户端请求,返回一个socket供通信
        pool.execute (new ServerTask(socket));//把任务提交至线程池
    }

}

(2)Executors类 的 newFixedThreadPool() 方法,返回一个 ExecutorService 的线程池

  • public static ExecutorService newFixedThreadPool( int nThreads )
  • 创建一个线程池,该线程池重用固定数量的从共享*队列中运行的线程。
  • 在任何时候,最多nThreads线程将处于主动处理任务。 如果所有线程处于活动状态时都会提交其他任务,则它们将等待队列中直到线程可用。
  • 如果任何线程由于在关闭之前的执行期间发生故障而终止,则如果需要执行后续任务,则新线程将占用它。

(3)将任务提交至线程池之后,线程池则主动处理任务。
(4)ServerTask 为一个用户自定义类,用来处理任务。

private static class ServerTask implements Runnable{
    private Socket socket;

    ServerTask(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
        	InetAddress clientAddress = socket.getInetAddress ();
            int clientPort = socket.getPort();

            System.out.printf ("有客户端连接上来:%s%d%n",clientAddress,clientPort);

            //获取输入字节流(即客户端发送来的消息)
            InputStream is = socket.getInputStream ();
            //字节流转换为字符流
            InputStreamReader isReader = new InputStreamReader (is);
            //字符流转换为缓冲字符流
            BufferedReader reader = new BufferedReader (isReader);

            //输出字符流
            OutputStream os = socket.getOutputStream ();
            PrintStream out = new PrintStream (os,true,"UTF-8");


            while(true){
                String line;
                while(!(line = reader.readLine ()).isEmpty ()){
                    System.out.println ("收到消息:" + line);
                    Scanner sc = new Scanner (System.in);
                    System.out.print ("请回复:");
                    String response = sc.nextLine ();
                    out.println (response);
                }
            }

        } catch (IOException e) {
            e.printStackTrace ();
        }

    }
}

完整程序:
https://github.com/WangWenQian12/Java_Practice/tree/master/JavaSE/IDEA/JavaWeb/TCP2/src

这样我们就实现了多个客户端连接一台服务器的功能。

相关标签: JavaWeb