为什么当我尝试 telnet 时 select 方法 return 0 立即出现?
why does select method return 0 immediately when I try to telnet it?
我不熟悉 Java Nio。我试着写了一个像这样的小演示:
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 秒,程序每 2 秒打印一次 "no event"。
但是当我尝试远程登录它时它开始打印 "no event" 非常 fast.It 似乎 select 方法 returns 值 0 没有被阻止。
为什么?这是第一个问题。
当我尝试像这样在 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();
}
}
然后我再次telnet它,select方法returns 1.
为什么?那就是第二个问题了。
第一次在这里提问。请原谅我糟糕的英语。
您在 select(long) 中提供的号码与 Thread.sleep(long) 不同。根据:
https://docs.oracle.com/javase/7/docs/api/java/nio/channels/Selector.html#select(long)
select 是一个阻塞操作,但它会在能够 select 通道后立即进行。因此,当您连接时,它会不断循环和输出。您提供的 long 值是告诉 select(long) 方法何时放弃尝试 select 一个通道,而不是让线程休眠。为了保证至少 2 秒的休眠,您需要在循环结束前添加 Thread.sleep(2000)。
至于return值,select() returns更新的键数,可能为零。当您再次使用 telnet 连接时,您将提供一个可以更新的新密钥。如果您只有一个连接,则无需 select 一个新的频道来收听。因此,没有任何东西被切换。如果您有两个连接,那么每次都修改其中一个连接是有意义的。
我不熟悉 Java Nio。我试着写了一个像这样的小演示:
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 秒,程序每 2 秒打印一次 "no event"。
但是当我尝试远程登录它时它开始打印 "no event" 非常 fast.It 似乎 select 方法 returns 值 0 没有被阻止。
为什么?这是第一个问题。
当我尝试像这样在 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();
}
}
然后我再次telnet它,select方法returns 1.
为什么?那就是第二个问题了。
第一次在这里提问。请原谅我糟糕的英语。
您在 select(long) 中提供的号码与 Thread.sleep(long) 不同。根据:
https://docs.oracle.com/javase/7/docs/api/java/nio/channels/Selector.html#select(long)
select 是一个阻塞操作,但它会在能够 select 通道后立即进行。因此,当您连接时,它会不断循环和输出。您提供的 long 值是告诉 select(long) 方法何时放弃尝试 select 一个通道,而不是让线程休眠。为了保证至少 2 秒的休眠,您需要在循环结束前添加 Thread.sleep(2000)。
至于return值,select() returns更新的键数,可能为零。当您再次使用 telnet 连接时,您将提供一个可以更新的新密钥。如果您只有一个连接,则无需 select 一个新的频道来收听。因此,没有任何东西被切换。如果您有两个连接,那么每次都修改其中一个连接是有意义的。