Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java NIO选择器OP_读取未触发_Java_Nio - Fatal编程技术网

Java NIO选择器OP_读取未触发

Java NIO选择器OP_读取未触发,java,nio,Java,Nio,现在为我工作 首先,我创建如下服务器: Selector readSelector=Selector.open(); 选择器acceptSelector=Selector.open(); ServerSocketChannel ServerSocketChannel=ServerSocketChannel.open(); serverSocketChannel.socket().bind(新的InetSocketAddress(8088)); serverSocketChannel.config

现在为我工作

首先,我创建如下服务器:

Selector readSelector=Selector.open();
选择器acceptSelector=Selector.open();
ServerSocketChannel ServerSocketChannel=ServerSocketChannel.open();
serverSocketChannel.socket().bind(新的InetSocketAddress(8088));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(acceptSelector,SelectionKey.OP_ACCEPT);
然后,在线程中运行以下命令:

while(acceptSelector.isOpen()){
acceptSelector.select();
迭代器迭代器=acceptSelector.selectedKeys().Iterator();
while(iterator.hasNext()){
SelectionKey next=iterator.next();
iterator.remove();
if(next.isAcceptable()){
SocketChannel SocketChannel=serverSocketChannel.accept();
socketChannel.configureBlocking(假);
socketChannel.register(读取选择器,选择键,操作读取);
System.out.println(“套接字接受”+socketChannel.getRemoteAddress());
//有工作发现,我可以得到控制台输出
}
}
}
接下来,我尝试读取数据的下一部分:

readSelector.select();
System.out.println(“读取选择器”);//这永远不会被触发
迭代器迭代器=acceptSelector.selectedKeys().Iterator();
while(iterator.hasNext()){
SelectionKey next=iterator.next();
iterator.remove();
if(next.isReadable()){
SocketChannel=(SocketChannel)next.channel();
ByteBuffer ByteBuffer=ByteBuffer.allocateDirect(16);
通道读取(byteBuffer);
System.out.println(“套接字读取”+byteBuffer);
}
}
为什么不触发读取选择器。选择()

客户机代码(为了便于测试,我没有在客户机中使用nio):

SocketChannel SocketChannel=SocketChannel.open();
socketChannel.connect(新的InetSocketAddress(“127.0.0.1”,8088));
睡眠(1000L);
OutputStream OutputStream=socketChannel.socket().getOutputStream();
DataOutputStream DataOutputStream=新的DataOutputStream(outputStream);
dataOutputStream.writeUTF(“这是数据”);
dataOutputStream.flush();
InputStream InputStream=socketChannel.socket().getInputStream();
DataInputStream DataInputStream=新的DataInputStream(inputStream);
字符串readUTF=dataInputStream.readUTF();
System.out.println(readUTF);
顺便说一句:我见过一些像这样的重用代码

Selector=Selector.open();
... ...
serverSocketChannel.register(选择器,SelectionKey.OP_ACCEPT);
... ...
socketChannel.寄存器(选择器,SelectionKey.OP_READ);
ServerSocketChannel
SocketChannel
使用相同的选择器,这将在我的演示上创建NPE(接受返回null),我使用
if isAcceptable,否则if isReadable
确保我选择了正确的键

问题1:为什么不触发操作读取?

问题2:为什么重用选择器会创建空值?

当您得到OP_READ时,您迭代了错误的选择器,因此您永远不会遇到可读键。您应该只使用一个选择器。发布获得NPE的代码,我会告诉你它有什么问题。注意:您的I/O代码无论如何都无法工作,因为您的
SocketChannel
无法理解
writeUTF()
数据,或者无法生成可由
readUTF()读取的数据。必须使用相同的选择器吗?若我想在另一个线程中读取进程,我必须在选择器之后调用它。选择?我并没有说“必须”,但并没有理由使用第二个选择器。选择器的全部思想是,您不需要另一个线程。