传入连接的Java NIO选择器和传入消息的选择器

时间:2012-10-25 18:19:04

标签: java sockets nio

我正在尝试使用NIO构建高效的Socket TCP / IP服务器。

我有接受连接的主线程,然后将其添加到另一个应该等待客户端消息然后读取它的线程。

当我只使用一个线程和一个选择器进行所有操作时,它工作得很好,但是当我试图使其适用于2个线程和2个选择器时,传入连接接受正在工作,但读取不是,我认为这是因为我的选择器阻止了线程,因此他不知道我已经注册了一个新的SocketChannel。

这是我的主要话题:

public static void main(String[] args) {
   try {
      System.out.println("Who's Around Server Started!");
      Selector connectionsSelector = null;
      ServerSocketChannel server = null;
      String host = "localhost";
      int port = 80;    
      LiveConnectionsManager liveConnectionsManager =
         new LiveConnectionsManager();
      liveConnectionsManager.start();
      connectionsSelector = Selector.open();
      server = ServerSocketChannel.open();
      server.socket().bind(new InetSocketAddress(host,port));
      server.configureBlocking(false);
      server.register(connectionsSelector, SelectionKey.OP_ACCEPT);
      while (true) {
         connectionsSelector.select();
         Iterator<SelectionKey> iterator =
            connectionsSelector.selectedKeys().iterator();
         while (iterator.hasNext()) {
            SelectionKey incomingConnection = iterator.next();
            iterator.remove();
            if( incomingConnection.isConnectable()) {
               ((SocketChannel)incomingConnection.channel()).finishConnect();
            }
            if( incomingConnection.isAcceptable()){
               acceptConnection(server.accept(), liveConnectionsManager);
            }
         }
      }
   } catch (Throwable e) {
      throw new RuntimeException("Server failure: " + e.getMessage());
   } 
}

private static void acceptConnection(
   SocketChannel acceptedConnection,
   LiveConnectionsManager liveConnectionsManager ) throws IOException
{
   acceptedConnection.configureBlocking(false);
   acceptedConnection.socket().setTcpNoDelay(true);
   System.out.println(
      "New connection from: " + acceptedConnection.socket().getInetAddress());
   liveConnectionsManager.addLiveConnection(acceptedConnection);
}

这是我的LiveConnectionsManager:

private Selector messagesSelector;

public LiveConnectionsManager(){
   try {
      messagesSelector = Selector.open();           
   } catch (IOException e) {
      System.out.println("Couldn't run LiveConnectionsManager");
   }
}


@Override
public void run() {
   try {
      System.out.println("LiveConnectionManager Started!");
      while(true) {             
         messagesSelector.select();
         Iterator<SelectionKey> iterator = messagesSelector.keys().iterator();
         while (iterator.hasNext()){
            SelectionKey newData = iterator.next();
            iterator.remove();
            if( newData.isReadable()){
               readIncomingData(((SocketChannel)newData.channel()));
            }
         }
      }
   } catch (IOException e) {
      e.printStackTrace();
   }
}

public void addLiveConnection( SocketChannel socketChannel )
   throws ClosedChannelException
{
   socketChannel.register(messagesSelector, SelectionKey.OP_READ);      
}

0 个答案:

没有答案