多线程池服务器在 Java 中侦听多个端口 -

Posted

技术标签:

【中文标题】多线程池服务器在 Java 中侦听多个端口 -【英文标题】:Multithreaded pooled server listening on multiple ports in Java - 【发布时间】:2021-10-28 02:03:01 【问题描述】:

我试图弄清楚如何创建一个 Java 多线程服务器,该服务器可以侦听多个端口,并为它接受请求的每个端口提供线程池。

我已经实现了一个在单个 eport 上监听的功能多线程池服务器,如下所示:

public void run() 
        synchronized (this) 
            this.runningThread = Thread.currentThread();
        
        openSocketServer();
        while (!isStopped()) 
            Socket clientSocket = null;
            try 
                clientSocket = this.serverSocket.accept();
             catch (IOException e) 
                if (isStopped()) 
                    System.out.println("Server Stopped.");
                    break;
                
                throw new RuntimeException("Error with accepting client connection", e);
            
            this.threadPool.submit(new HandlerRichieste(clientSocket, this));
        
        this.threadPool.shutdown();
        System.out.println("Server stopped");
    

我设法使用 NIO 库实现了一个侦听多个端口的服务器;这个实现的问题是它只使用一个线程来处理来自不同端口的请求,因此按顺序处理它们并降低性能:

Selector selector = Selector.open();

int[] ports = 4000,4001,6000;

for (int port : ports) 
   ServerSocketChannel server = ServerSocketChannel.open();
   server.configureBlocking(false);

   server.socket().bind(new InetSocketAddress(port));
   // from here we are only interested when accept evens occur on this socket
   server.register(selector, SelectionKey.OP_ACCEPT); 


while (selector.isOpen()) 
   selector.select();
   Set readyKeys = selector.selectedKeys();
   Iterator iterator = readyKeys.iterator();
   while (iterator.hasNext()) 
      SelectionKey key = (SelectionKey) iterator.next();
      if (key.isAcceptable()) 
         SocketChannel client = server.accept(); //SERVER CANNOT BE RESOLVED!!!!
         Socket socket = client.socket();
         // create new thread to deal with the connection coming from that port (closing both socket and client when done)
      
   

如何合并它们 - 导致服务器监听多个端口,每个端口都有一个线程池? 是否有可能在不使用 NIO 库的情况下创建一个多线程池服务器来监听多个端口? 如果是这样,谁能告诉我在没有 Java NIO 的情况下为每个端口设置线程池的机制?

【问题讨论】:

如果您使用Selector,通常的方法是使用一个只执行服务选择器事件的线程。然后当你得到一个数据包/一些工作要做时,你将数据包发送到一个单独的线程池来执行工作。然后选择器线程立即返回为选择器提供服务。 如果您想查看一些真正的工作代码,请查看 Apache Web Server 源代码,它也使用 select()poll() 调用。我相信相关代码在listen.c:github.com/apache/httpd/blob/trunk/server/listen.c @markspace 谢谢,这正是我在使用 NIO 的选择器实现“服务器侦听多个端口”时所做的(我没有添加整个代码以提供最低限度可重现的示例,但正如您从代码中看到的那样,有一个线程在侦听所有端口并将数据包发送到单独的线程池)。不幸的是,由于它使选择事件的服务顺序进行,我需要有多个线程池 - 每个端口一个 - 这样如果有来自多个端口的多个请求,我就不会一次只为一个端口提供服务。 @markspace Apache Web Server 源代码非常有趣,它肯定重申了标准是什么——显然我需要的选择器(NIO 库)无法完成。尽管如此,我确实需要关于如何修改问题中的第一个多线程服务器实现的建议,以便它可以接受来自给定端口集的请求(因为“为每个端口创建一个线程池”部分将非常容易之后实施)。 @markspace 创建不同的多线程池服务器 - 为每个端口准备 - 也许可以解决我的问题?虽然我将如何实施该路线(我是新手)? 【参考方案1】:

您已经能够创建一个服务器,其中一个线程在一个端口上等待连接,并使用来自一个特定池的线程为传入的连接提供服务。

是什么阻止了您三次创建这种模式?然后,您正在侦听三个端口并使用来自三个特定线程池的线程提供传入连接。你唯一需要注意的是: 在一个套接字上等待连接可能会阻塞线程。

作为一种解决方案,只需创建三个线程,每个线程监听一个端口。

【讨论】:

这么简单的解决方案,谢谢!将为每个端口实现一个新的套接字,不需要 NIO!

以上是关于多线程池服务器在 Java 中侦听多个端口 -的主要内容,如果未能解决你的问题,请参考以下文章

Java如何实现多线程传输文件,就像迅雷下载一样,开十多个线程分段传送字节流?

什么叫线程池?线程池如何使用?

java多线程总结五:线程池的原理及实现

Java线程池详解

java线程池技术

Java线程和线程池