代码如下:
// 反复循环,等待IO
while (true) {
// 等待某信道就绪(或超时)
if (selector.select(TimeOut) == 0) {// 监听注册通道,当其中有注册的 IO
// 操作可以进行时,该函数返回,并将对应的
// SelectionKey 加入 selected-key
// set
log.info("服务器独自等待.");
continue;
}
// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
// Selected-key Iterator 代表了所有通过 select() 方法监测到可以进行 IO 操作的 channel
// ,这个集合可以通过 selectedKeys() 拿到
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while (keyIter.hasNext()) {
SelectionKey key = keyIter.next();
try {
if (key.isAcceptable()) {
// 有客户端连接请求时
protocol.handleAccept(key);
}
if (key.isReadable()) {// 判断是否有数据发送过来
// 从客户端读取数据
protocol.handleRead(key);
}
if (key.isValid() && key.isWritable()) {// 判断是否有效及可以发送给客户端
// 客户端可写时
protocol.handleWrite(key);
}
} catch (IOException ex) {
// 出现IO异常(如客户端断开连接)时移除处理过的键
log.error("IO异常(如客户端断开连接)", ex);
keyIter.remove();
continue;
}
// 移除处理过的键
keyIter.remove();
}
}
奇怪的现象是,我关闭了客户端后,这个keyIter里面一直会有一个read的key存在,按说客户端关闭了应该阻塞了
} catch (IOException e) {
e.printStackTrace();
//如果客户端断开 需要结束 不然还会循环进来
sk.channel().close();
} finally {
//取消选择键
it.remove();
}
当客户端关闭了之后,相应的客户端的这个socket的read connection也关闭了,所以你在服务器端用select()会在read里得到这个socket的。
参考U nix Network Programming Vol1的select()部分,里面有一张表格告诉你什么时候一个socket可读、可写、出错。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。