【问题标题】:multi-client program without multi-threading没有多线程的多客户端程序
【发布时间】:2015-10-30 20:24:53
【问题描述】:

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

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

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

【问题讨论】:

  • 喜欢在一个类中有两个套接字?要不然是啥?这是给服务器的?还是客户?
  • 你可以做一个非阻塞IO的单线程服务器。然而我不会。多线程——和多个 CPU——是扩展单个盒子的唯一方法。现代系统过于依赖多线程。删除它不是最佳做法。
  • @3kings 客户端需要相互通信...
  • @markspace 什么意思?(单线程)怎么可能有多个客户端
  • @faraa 请参见下面 Walter 的示例。那就是我的意思。请注意,他将选择器设置为非阻塞模式 (server.configureBlocking(false))。

标签: java sockets client-server


【解决方案1】:

好吧,我只是把它放在一起。这只是一个使用 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();
  }

【讨论】:

  • 谢谢...所以没有办法使用传统的IO来解决这个问题...是吗?
  • 如果你的意思是 java.io 包,那么没有。这些都是阻塞套接字。如果您想查看我没有经验但得到很多赞誉的图书馆,您可以查看netty.io
猜你喜欢
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2016-01-10
  • 2017-07-17
相关资源
最近更新 更多