今天在学习java nio的时候碰到了一个奇怪的问题,在客户端断开连接后,出现了不断产生新OP_READ事件的问题。
while(true){
if(selector.select(1000) == 0){ // 断开连接后这里没有延时的效果
System.out.println("==");
continue;
}
Iterator<SelectionKey> itr = selector.selectedKeys().iterator();
while (itr.hasNext()){
SelectionKey key = itr.next();
if(key.isAcceptable()){
handleAccept(key);
}
if(key.isReadable()){ // 断开连接后这里会不断判定为true
handleRead(key);
}
itr.remove();
}
}
原因就在于断开连接后,为了让你知道连接已断开,所以会产生OP_READ事件。
那么该怎么判断呢?
其实只要判断一下byteBuffer的大小就可以了,当byteBuffer的长度小于0时,说明连接断开了,那么把channel关闭就可以了。如下:
long readLength = sc.read(buf);
if(readLength < 0) sc.close();
参考:https://stackoverflow.com/questions/4139300/socketchannel-fires-isreadable-but-nothing-to-read