为什么我会收到 CancelledKeyException?
Why do I get a CancelledKeyException?
为什么我会收到取消密钥异常错误?谁能帮帮我吗?客户端哪部分代码出错了?
java.nio.channels.CancelledKeyException
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73)
at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:82)
at viaNIO.clientasync2.write(clientasync2.java:130)
at viaNIO.clientasync2.run(clientasync2.java:53)
at java.lang.Thread.run(Thread.java:745)
java.nio.channels.CancelledKeyException
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73)
at sun.nio.ch.SelectionKeyImpl.readyOps(SelectionKeyImpl.java:87)
at java.nio.channels.SelectionKey.isReadable(SelectionKey.java:289)
at viaNIO.clientasync2.run(clientasync2.java:55)
at java.lang.Thread.run(Thread.java:745)
这是客户端的代码:
while (!Thread.interrupted()) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (key.isValid()) {
if (key.isConnectable()) {
System.out.println("Connected to the server");
connect(key);
}
if (key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
}
}
这是更新后的代码:
while (!Thread.interrupted()) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (key.isValid() && key.isConnectable()) {
connect(key);
} else {
if (key.isValid() && key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isValid() && key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
}
}
这也是我写方法的代码
private void write(SelectionKey key) throws IOException {
SocketChannel socket = (SocketChannel) key.channel();
RandomAccessFile aFile = null;
try {
File f = new File("D:/test.rar");
aFile = new RandomAccessFile(f, "r");
ByteBuffer buffer = ByteBuffer.allocate(300000000);
FileChannel inChannel = aFile.getChannel();
while (inChannel.read(buffer) > 0) {
buffer.flip();
socket.write(buffer);
buffer.clear();
}
aFile.close();
socket.close();
inChannel.close();
Thread.sleep(1000);
key.interestOps(SelectionKey.OP_READ);
} catch (Exception e) {
e.printStackTrace();
}
}
读取方法的代码
private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1000);
readBuffer.clear();
int length;
try {
length = channel.read(readBuffer);
} catch (IOException e) {
System.out.println("Reading problem, closing connection");
key.cancel();
channel.close();
return;
}
if (length == -1) {
System.out.println("Nothing was read from server");
channel.close();
key.cancel();
return;
}
readBuffer.flip();
byte[] buff = new byte[1024];
readBuffer.get(buff, 0, length);
System.out.println("Server said: " + new String(buff));
if (readCnt != 1) {
key.interestOps(SelectionKey.OP_WRITE);
readCnt++;
} else {
key.cancel();
close();
}
}
连接方法的代码
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
}
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
}
因为 connect()
或 write()
在您进入 isReadable()
测试之前关闭了频道或取消了密钥。您需要继续重新测试 isValid()
。您还需要在 isConnectable()
块之后添加一个 else
,因为 OP_CONNECT 不能与 OP_WRITE 或 OP_READ 中的任何一个一起触发:
if (key.isValid() && key.isConnectable()) {
System.out.println("Connected to the server"); // see below
connect(key);
} else {
if (key.isValid() && key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isValid() && key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
还有消息"Connected to the server"
放错地方了。您即将尝试完成连接:当且仅当 finishConnect()
returns true
你真的连接了。
为什么我会收到取消密钥异常错误?谁能帮帮我吗?客户端哪部分代码出错了?
java.nio.channels.CancelledKeyException
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73)
at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:82)
at viaNIO.clientasync2.write(clientasync2.java:130)
at viaNIO.clientasync2.run(clientasync2.java:53)
at java.lang.Thread.run(Thread.java:745)
java.nio.channels.CancelledKeyException
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73)
at sun.nio.ch.SelectionKeyImpl.readyOps(SelectionKeyImpl.java:87)
at java.nio.channels.SelectionKey.isReadable(SelectionKey.java:289)
at viaNIO.clientasync2.run(clientasync2.java:55)
at java.lang.Thread.run(Thread.java:745)
这是客户端的代码:
while (!Thread.interrupted()) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (key.isValid()) {
if (key.isConnectable()) {
System.out.println("Connected to the server");
connect(key);
}
if (key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
}
}
这是更新后的代码:
while (!Thread.interrupted()) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (key.isValid() && key.isConnectable()) {
connect(key);
} else {
if (key.isValid() && key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isValid() && key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
}
}
这也是我写方法的代码
private void write(SelectionKey key) throws IOException {
SocketChannel socket = (SocketChannel) key.channel();
RandomAccessFile aFile = null;
try {
File f = new File("D:/test.rar");
aFile = new RandomAccessFile(f, "r");
ByteBuffer buffer = ByteBuffer.allocate(300000000);
FileChannel inChannel = aFile.getChannel();
while (inChannel.read(buffer) > 0) {
buffer.flip();
socket.write(buffer);
buffer.clear();
}
aFile.close();
socket.close();
inChannel.close();
Thread.sleep(1000);
key.interestOps(SelectionKey.OP_READ);
} catch (Exception e) {
e.printStackTrace();
}
}
读取方法的代码
private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1000);
readBuffer.clear();
int length;
try {
length = channel.read(readBuffer);
} catch (IOException e) {
System.out.println("Reading problem, closing connection");
key.cancel();
channel.close();
return;
}
if (length == -1) {
System.out.println("Nothing was read from server");
channel.close();
key.cancel();
return;
}
readBuffer.flip();
byte[] buff = new byte[1024];
readBuffer.get(buff, 0, length);
System.out.println("Server said: " + new String(buff));
if (readCnt != 1) {
key.interestOps(SelectionKey.OP_WRITE);
readCnt++;
} else {
key.cancel();
close();
}
}
连接方法的代码
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
}
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
}
因为 connect()
或 write()
在您进入 isReadable()
测试之前关闭了频道或取消了密钥。您需要继续重新测试 isValid()
。您还需要在 isConnectable()
块之后添加一个 else
,因为 OP_CONNECT 不能与 OP_WRITE 或 OP_READ 中的任何一个一起触发:
if (key.isValid() && key.isConnectable()) {
System.out.println("Connected to the server"); // see below
connect(key);
} else {
if (key.isValid() && key.isWritable()) {
System.out.println("Writing to the server");
write(key);
}
if (key.isValid() && key.isReadable()) {
System.out.println("Reading from the server");
read(key);
}
}
还有消息"Connected to the server"
放错地方了。您即将尝试完成连接:当且仅当 finishConnect()
returns true
你真的连接了。