正在检测插座断开连接?
我有点沮丧,这不能以优雅的方式处理,在尝试了不同的解决方案(这个,这个和其他几个)在几个SO问题的回答中提到的之后,我仍然无法设法检测插座断开连接(通过拔下电缆)。
我正在使用NIO非阻塞套接字,一切都很完美,除了我发现没有办法检测到服务器断开连接。
我有以下代码:
while (true) {
handlePendingChanges();
int selectedNum = selector.select(3000);
if (selectedNum > 0) {
SelectionKey key = null;
try {
Iterator<SelectionKey> keyIterator = selector.selelctedKeys().iterator();
while (keyIterator.hasNext()) {
key = keyIterator.next();
if (!key.isValid())
continue;
System.out.println("key state: " + key.isReadable() + ", " + key.isWritable());
if (key.isConnectable()) {
finishConnection(key);
} else if (key.isReadable()) {
onRead(key);
} else if (key.isWritable()) {
onWrite(key);
}
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("I am happy that I can catch some errors.");
} finally {
selector.selectedKeys().clear();
}
}
}
在读取套接字通道时,我拔下电缆,开始旋转并返回0,现在我没有机会读取或写入通道,因为主要的读取和写入代码被保护,现在这是我脑海中出现的第一个混乱,从这个答案来看,据说当通道断开时, select() 将返回,通道的选择键将指示可读/可写,但显然不是这种情况,键未被选中,仍然返回 0。Selector.select()
if (selectedNum > 0)
select()
此外,从EJP对类似问题的回答中可以看出:
如果对等体关闭套接字:
- read() 返回 -1
- readLine() 返回空值
- readXXX() 为任何其他 X 抛出 EOFException。
这里的情况也不是这样,我尝试注释掉并用于获取所有键,无论它们是否被选中,从这些键读取不会返回-1(返回0),并且写入这些键不会被抛出。我只注意到一件事,即使没有选择密钥,返回true而返回false(我想这可能是因为我没有为OP_WRITE注册密钥)。if (selectedNum > 0)
selector.keys().iterator()
EOFException
key.isReadable()
key.isWritable()
我的问题是为什么Java套接字表现得像这样,或者我做错了什么?