【问题标题】:Writing Java Server to handle multiple client concurrently (simultaneously)编写 Java Server 以同时(同时)处理多个客户端
【发布时间】:2019-02-26 12:09:57
【问题描述】:

我正在开发一个程序,其中有一个服务器和客户端类,但目前它一次只处理一个客户端。 我需要服务器能够使用多线程同时(同时)处理多个客户端。

这是我的服务器代码;如何更改它以同时处理多个客户端?

public static void main(String[] args) throws IOException {

       ServerSocket socket = new ServerSocket(8945);
       Server serverInstance = new Server();

       System.out.println("Server is running. Waiting for client.");

       while(true) {
           server.socket = s.accept();
           System.out.println("Client connected");
           serverInstance.run();
           System.out.println("Client disconnected. Waiting for new client.");
       }
   }

   public void run() {
       try {
           try {
               in = new Scanner(socket.getInputStream());
               out = new PrintWriter(socket.getOutputStream());
               RequestHandlingMethod();  

           } finally {
               socket.close();
           }

       } catch (IOException e) {
           System.err.println(e);
       }

}

【问题讨论】:

    标签: java multithreading client-server


    【解决方案1】:

    创建一个单独的类来处理客户端。让它实现Runnable,这样你就可以用它开始一个单独的Thread

    public class ClientHandler implements Runnable {
    
       private final Socket socket;
    
       public ClientHandler(Socket socket) {
         this.socket = socket;
       }
    
        public void run() {
           try (Socket socket = this.socket;
                Scanner in = new Scanner(socket.getInputStream();
                PrintWriter out = new PrintWriter(socket.getOutputStream()) {
    
                   //todo: do whatever you need to do
    
    
           } catch (IOException ex) {
               ex.printStackTrace();
           }
    
           System.out.println("Client disconnected.");
        }  
    }
    

    然后在你的服务器上做:

           System.out.println("Waiting for new client connection");
           Socket clientSocket = s.accept();
           System.out.println("Client connected");
           new Thread(new ClientHandler(clientSocket)).start();
    

    如果您不想创建大量一次性线程,您可能需要考虑使用带有缓存线程池的ExecutorService(如果您愿意,也可以选择其他线程池)。

    您只需使用ExecutorService executor = ExecutorService.newCachedThreadPool() 创建一个新的ExecutorService,然后在您的循环中执行以下操作:

           System.out.println("Waiting for new client connection");
           Socket clientSocket = s.accept();
           System.out.println("Client connected");
           executor.submit(new ClientHandler(clientSocket));
    

    如果您认为您将拥有大量并发客户端,则可能需要考虑使用带有 NIO 的非阻塞服务器。它将有 1 个单独的事件循环线程(不会在 accept 上阻塞)并在那里处理所有 I/O 事件,并且您可以拥有一个执行客户端处理逻辑的工作线程池。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-17
      • 2015-05-06
      • 2017-04-08
      • 1970-01-01
      • 2014-11-23
      • 2017-12-26
      • 1970-01-01
      • 2021-04-08
      相关资源
      最近更新 更多