java - 为什么当我尝试 telnet 时选择方法立即返回 0?
问题描述
我不熟悉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 秒打印一次“无事件”。
但是当我尝试远程登录它并且它开始非常快地打印“无事件”时。似乎选择方法返回值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方法返回1。
为什么?这是第二个问题。
第一次在这里提问。请原谅我糟糕的英语。
解决方案
您在 select(long) 中提供的数字与 Thread.sleep(long) 不同。根据:
https://docs.oracle.com/javase/7/docs/api/java/nio/channels/Selector.html#select(long)
select 是一个阻塞操作,但是一旦它能够选择一个通道,它就会继续。因此,当您连接时,它将不断循环和输出。您提供的 long 值是告诉 select(long) 方法何时放弃尝试选择通道,而不是让线程休眠。为了保证至少 2 秒的睡眠,您需要在循环结束之前添加 Thread.sleep(2000)。
至于返回值,select() 返回被更新的key的个数,可能为零。当您再次使用 telnet 连接时,您将提供一个可以更新的新密钥。如果您只有一个连接,则无需选择新频道来收听。因此,没有任何东西被切换。如果您有两个连接,那么每次都会修改其中一个是有意义的。
推荐阅读
- ios - CORE 数据:根据对象的关系获取对象
- python - BERT 标记 URL
- python - 多个用户可以写入一个 SQLite 数据库,还是纯粹是本地的
- python - 如何检测用户何时使用 pygame 单击矩形?
- google-cloud-platform - 对于 Bigquery 表模式,如何将列的模式从 NULLABLE 更改为 REQUIRED?
- php - 条纹 PHP SDK 问题
- introspection - 如何使用 openiddict 进行内省以返回电子邮件等信息
- javascript - 将对象推入嵌套减速器数组?
- arrays - 最大平均子数组 I,Leetcode。超过时间限制
- unity3d - 我怎样才能使我的统一树从更远的地方加载到叶子中?