0

効率的なソケット TCP/IP サーバーを構築するために NIO を使用しようとしています。

接続を受け入れるメインスレッドがあり、クライアントからのメッセージを待ってから読み取る別のスレッドに追加します。

すべての操作に1つのスレッドと1つのセレクターのみを使用している場合はうまく機能しますが、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);      
}
4

0 に答える 0