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

时间:2015-10-30 20:24:53

标签: java sockets client-server

有没有办法在没有多线程的情况下使用Java中的套接字编写多客户端程序?

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

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

1 个答案:

答案 0 :(得分:2)

嗯,我把它扔在了一起。这只是用 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();
  }