没有多线程的多客户端程序

multi-client program without multi-threading

有没有什么方法可以在 Java 中使用套接字而不使用多线程来编写多客户端程序?

我听说过套接字映射,但它是如何工作的?

我知道多线程,但现在我不应该使用它。

好吧,我只是把它放在一起。这只是使用 java.nio 进行编程的示例。我认为这段代码相当简单。它将 ServerSocket 绑定到端口 3000-3009。每当客户端发送数据时,它都会将其回显给他们。它可以处理尽可能多的连接。您当然应该实施更多的错误处理,但这样阅读起来会更难以供参考。以这种方式处理数据比使用每个客户端线程方法要困难一些,如果您希望有一个混合类型的服务器,其中非活动连接进入非阻塞模式,当您开始接收数据时,您可以跳回阻塞模式缓存线程池。

要测试它,只需打开 shell 并使用 telnet localhost 3000

  Selector selector = Selector.open();
  for(int port=3000;port<3010;port++){
     ServerSocketChannel server = ServerSocketChannel.open();
     server.configureBlocking(false);
     server.socket().bind(new InetSocketAddress(port));
     server.register(selector, SelectionKey.OP_ACCEPT);
     System.out.println("Bound to " + server);
  }

  ByteBuffer buffer = ByteBuffer.allocate(0x4000);
  while(selector.isOpen()){
     selector.select();
     Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
     while(keys.hasNext()){
        SelectionKey key = keys.next();
        if(!key.isValid()) continue;

        if(key.isReadable()){
           buffer.clear();
           SocketChannel socket = (SocketChannel)key.channel();
           if(socket.read(buffer) == -1){ //-1 is end of stream
              System.out.println("Client Disconnected " + socket);
              socket.close();
              continue;
           }else{
              buffer.flip();
              socket.write(buffer); //echo data back to client
           }

        }else if(key.isAcceptable()){
           ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
           SocketChannel socket = serverChannel.accept();
           socket.configureBlocking(false);
           socket.register(selector, SelectionKey.OP_READ);
           System.out.println("Client Connected " + socket);
        }
     }
     selector.selectedKeys().clear();
  }