Java Server - 多个端口?

Myn*_*Myn 11 java multithreading tcp serversocket

我即将编程服务器,但我想知道我的想法是否可行.我的程序将输出到多个端口上的多个客户端 - 每个端口可以被多个客户端访问.

通常我会使用线程套接字服务器,但在这种情况下我需要它为多个端口工作.我想到的用法是在下面的模糊伪代码中:

  • 启动服务器
  • 侦听多个端口上的传入连接
  • 识别要连接的端口
    • 如果是端口1,则启动一个侦听客户端并输出消息类型的线程 x
    • 如果是端口2,则启动一个侦听客户端并输出消息类型的线程 y

希望这有点意义,你可以看到我正在尝试做什么.简单地说:听取选定的端口,根据连接的端口创建一个线程套接字连接.

这是可行的,还是我要结束多线程线程套接字服务器?

编辑:更改措辞以更好地反映问题.

Dun*_*nes 15

我不认为单个实例ServerSocket可以监听多个端口.你当然可以有多个ServerSockets.但是,正如您所知,ServerSocket.accept块.

你可以使用的是一个ServerSocketChannel.它们以类似的方式使用,但不会阻塞.

如果在ServerSocketChannel.accept调用时没有挂起的连接,则它只返回null.

您可以使用带有一Selector组通道和块的a,直到至少有一个具有挂起连接.

我不记得如何使用它们的细节,但这个似乎是一个体面的代码示例.

编辑:这是我自己的例子(伪ish)

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));
// 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();
         Socket socket = client.socket();
// create new thread to deal with connection (closing both socket and client when done)
      }
   }
}

// tidy up selector and channels
Run Code Online (Sandbox Code Playgroud)


小智 9

你好,让我直截了当.您要做的是创建一个可以侦听多个端口的服务器,当您获得新连接时,您希望能够告诉该连接使用哪个端口,这是正确的吗?如果是这样的话,你可以使用java.nio包很容易地做到这一点.

我们将使用Selector进行准备选择,使用ServerSocketChannel来监听传入的连接.

首先,我们需要声明我们的Selector.

Selector selector = Selector.open();
Run Code Online (Sandbox Code Playgroud)

现在让我们创建一个要监听的端口列表并开始监听它们.

int ports[] = new int[] { 1234, 4321 };

// loop through each port in our list and bind it to a ServerSocketChannel
for (int port : ports) {
    ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(false);
    serverChannel.socket().bind(new InetSocketAddress(port));
    serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
Run Code Online (Sandbox Code Playgroud)

现在为SelectionKey处理过程.

while (true) {
    selector.select();

    Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
    while (selectedKeys.hasNext()) {
        SelectionKey selectedKey = selectedKeys.next();

        if (selectedKey.isAcceptable()) {
            SocketChannel socketChannel = ((ServerSocketChannel) selectedKey.channel()).accept();
            socketChannel.configureBlocking(false);
            switch (socketChannel.socket().getPort()) {
                case 1234:
                    // handle connection for the first port (1234)
                    break;
                case 4321:
                    // handle connection for the secon port (4321)
                    break;
            }
        } else if (selectedKey.isReadable()) {
            // yada yada yada
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

对于这样一个简单的任务来说,也许不需要switch语句,但这是为了便于阅读和理解.

请记住,此服务器是以非阻塞异步方式设置的,因此您执行的所有I/O调用都不会阻止当前线程.所以不要SelectionKey处理过程中启动任何新线程.

另外,我知道这并不完全回答你的问题(它可能,它可能没有),但它实际上会让你理解如何使用这个java.nio包创建一个可以监听多个端口的非阻塞异步服务器.