问题描述
使用Java NIO 编写一个Server。端口是9999,使用 select方法阻塞返回,超时时间为2秒。
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(9999)).configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
for (; ; ) {
int select = selector.select(2_000);
if (select == 0) {
System.out.println("no event");
continue;
}
System.out.println("select = " + select);
}
在没有连接请求时,每隔2秒钟正常打印:
no event
no event
no event
使用 telnet 尝试发起请求后,控制台快速(select 方法立即返回)打印:
no event
no event
no event
并没有走到下面一行代码:
System.out.println("select = " + select);
但是在 for 循环里加上了下面几行代码后,代码变成下面的样子,于是情况发生了变化:
for (; ; ) {
int select = selector.select();
if (select == 0) {
System.out.println("no event");
continue;
}
System.out.println("select = " + select);
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
System.out.println("iterator = " + iterator.hasNext());
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
}
}
此时返回的的 select 值已经不是0了,控制台开始打印:
select = 1
iterator = true
select = 1
iterator = true
select = 1
iterator = true
select = 1
iterator = true
问题:
select 返回值为什么会受到后面几行遍历 key 事件代码的影响?而且我测试过,如果不在此 while 循环中 remove 事件,则 select 返回值依旧是0,但是 remove 后,返回值则为 1.
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
}
还有一个问题就是select 开始是超时阻塞返回,但是如果通过 telnet 发起连接后,则快速返回,且返回值为 0,why