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

用于传入连接的Java NIO选择器和用于传入消息的选择器,java,sockets,nio,Java,Sockets,Nio,我正在尝试使用NIO构建一个高效的套接字TCP/IP服务器 我有一个主线程,它接受连接,然后将它添加到另一个线程,该线程应该等待来自客户端的消息,然后读取它 当我只使用一个线程和一个选择器来执行所有操作时,效果非常好,但当我尝试使用两个线程和两个选择器时,传入的连接accept正常工作,但读数不正常,我认为这是因为我的选择器阻塞了线程,因此他不知道我已经注册了一个新的SocketChannel 这是我的主线: public static void main(String[] args) {

我正在尝试使用NIO构建一个高效的套接字TCP/IP服务器

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

当我只使用一个线程和一个选择器来执行所有操作时,效果非常好,但当我尝试使用两个线程和两个选择器时,传入的连接accept正常工作,但读数不正常,我认为这是因为我的选择器阻塞了线程,因此他不知道我已经注册了一个新的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);
}
publicstaticvoidmain(字符串[]args){
试一试{
System.out.println(“谁在服务器旁启动了!”);
选择器连接Selector=null;
serversocketchannelserver=null;
String host=“localhost”;
int端口=80;
LiveConnectionManager LiveConnectionManager=
新建LiveConnectionsManager();
liveConnectionsManager.start();
connectionsSelector=Selector.open();
server=ServerSocketChannel.open();
server.socket().bind(新的InetSocketAddress(主机、端口));
server.configureBlocking(false);
注册(ConnectionSelector,SelectionKey.OP_ACCEPT);
while(true){
connectionsSelector.select();
迭代器迭代器=
ConnectionSelector.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);
}
}
}
}捕获(可丢弃的e){
抛出新的RuntimeException(“服务器故障:+e.getMessage());
} 
}
专用静态连接(
SocketChannel接受连接,
LiveConnectionManager(LiveConnectionManager)引发IOException
{
acceptedConnection.configureBlocking(false);
acceptedConnection.socket().setTcpNoDelay(true);
System.out.println(
新连接来自:“+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);      
}
专用选择器消息选择器;
公共LiveConnectionsManager(){
试一试{
messagesSelector=Selector.open();
}捕获(IOE异常){
System.out.println(“无法运行LiveConnectionManager”);
}
}
@凌驾
公开募捐{
试一试{
System.out.println(“LiveConnectionManager已启动!”);
虽然(正确){
messagesSelector.select();
迭代器迭代器=messagesSelector.keys().Iterator();
while(iterator.hasNext()){
SelectionKey newData=iterator.next();
iterator.remove();
if(newData.isReadable()){
readIncomingData(((SocketChannel)newData.channel());
}
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
public void addLiveConnection(SocketChannel SocketChannel)
抛出ClosedChannel异常
{
socketChannel.register(messages选择器,SelectionKey.OP_READ);
}

与其构建自己的NIO服务器,不如看一看。在一个线程中完成这一切。您的设计没有很大的优势,而且很难实现多线程NIO。