java nio在注册写入操作后无法读取
我在使用JavaNIO进行网络时遇到了一个问题 我在线程中启动服务器,并在选择器中注册读取操作。另一个线程连接到服务器java nio在注册写入操作后无法读取,java,sockets,nio,Java,Sockets,Nio,我在使用JavaNIO进行网络时遇到了一个问题 我在线程中启动服务器,并在选择器中注册读取操作。另一个线程连接到服务器 客户端向服务器写入一个字节 服务器读取数据并向客户端返回一个字节 客户端获得响应并再次向服务器写入一个字节 服务器循环步骤2 但服务器无法成功执行步骤4,因为我无法再从选择器获取任何读取密钥。为什么?我以前注册过,客户已经写了数据 下面是我的代码: package test; import java.io.IOException; import java.net.InetSo
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class JavaNIO {
public static void main(String[] args) throws Exception {
final Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(5555));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
new Thread() {
public void run() {
while(true) {
try {
long count = selector.select();
if(count == 0) continue;
Iterator<SelectionKey> itKey = selector.selectedKeys().iterator();
while(itKey.hasNext()) {
SelectionKey key = itKey.next();
itKey.remove();
if(key.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel)key.channel();
SocketChannel socket = channel.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ);
}
if(key.isReadable()) {
ByteBuffer buffer= ByteBuffer.allocate(1);
SocketChannel channel = (SocketChannel)key.channel();
while(true) {
buffer.flip();
int len = channel.read(buffer);
if(len == 0) break;
buffer.clear();
}
channel.read(buffer);
channel.register(selector, SelectionKey.OP_WRITE, null);
}
if(key.isWritable()) {
SocketChannel channel = (SocketChannel) key.channel();
channel.write(ByteBuffer.wrap("ce".getBytes()));
key.cancel();
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
try {
Socket socket = new Socket("localhost", 5555);
byte[] reads = new byte[1024];
for(int i = 0; i < 1000; i++) {
socket.getOutputStream().write(new byte[]{1});
socket.getInputStream().read(reads);
System.out.println(new String(reads));
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
封装测试;
导入java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入java.nio.ByteBuffer;
导入java.nio.channels.SelectionKey;
导入java.nio.channels.Selector;
导入java.nio.channels.ServerSocketChannel;
导入java.nio.channels.SocketChannel;
导入java.util.Iterator;
公共类JavaNIO{
公共静态void main(字符串[]args)引发异常{
最终选择器=Selector.open();
ServerSocketChannel serverChannel=ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(新的InetSocketAddress(5555));
serverChannel.register(选择器、SelectionKey.OP_ACCEPT);
新线程(){
公开募捐{
while(true){
试一试{
长计数=选择器。选择();
如果(计数=0)继续;
迭代器itKey=selector.selectedKeys().Iterator();
while(itKey.hasNext()){
SelectionKey=itKey.next();
itKey.remove();
if(key.isAcceptable()){
ServerSocketChannel=(ServerSocketChannel)key.channel();
SocketChannel socket=channel.accept();
socket.configureBlocking(false);
插座.寄存器(选择器,SelectionKey.OP_READ);
}
if(key.isReadable()){
ByteBuffer缓冲区=ByteBuffer.allocate(1);
SocketChannel=(SocketChannel)key.channel();
while(true){
flip();
int len=通道读取(缓冲区);
如果(len==0)中断;
buffer.clear();
}
通道读取(缓冲区);
通道寄存器(选择器,SelectionKey.OP_WRITE,null);
}
if(key.isWritable()){
SocketChannel=(SocketChannel)key.channel();
channel.write(ByteBuffer.wrap(“ce.getBytes());
键。取消();
}
}
}捕获(例外e){
e、 printStackTrace();
}
}
}
}.start();
新线程(){
公开募捐{
试一试{
套接字=新套接字(“localhost”,5555);
字节[]读取=新字节[1024];
对于(int i=0;i<1000;i++){
socket.getOutputStream().write(新字节[]{1});
socket.getInputStream().read(读取);
System.out.println(新字符串(读取));
}
}捕获(未知后异常e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}.start();
}
}
您为OP\u WRITE
重新注册了频道,因此它的兴趣不再包括OP\u READ
。如果你两者都想要,就相应地改变。”或者把它们放在一起