当前位置:  开发笔记 > 编程语言 > 正文

Java NIO select()返回没有选中的键 - 为什么?

如何解决《JavaNIOselect()返回没有选中的键-为什么?》经验,为你挑选了2个好方法。

在编写一些测试代码时,我发现Selector.select()可以返回而不包含要处理的任何键的Selector.selectedKeys().当我注册一个accept()ed频道时,会发生这种情况

SelectionKey.OP_READ | SelectionKey.OP_CONNECT

作为感兴趣的业务.

根据文档,select()应该在以下时间返回:

1)有可以采取行动的渠道.

2)您明确调用Selector.wakeup() - 未选择任何键.

3)显式Thread.interrupt()执行select()的线程 - 没有选择键.

如果我在select()之后没有键,我必须在case(2)和(3)中.但是,我的代码不是调用wakeup()或interrupt()来启动这些返回.

关于是什么导致这种行为的任何想法?



1> Alexander..:

简短回答:OP_CONNECT从您感兴趣的操作列表中删除已接受的连接 - 已连接已接受的连接.

我设法重现了这个问题,这可能正是你发生的事情:

import java.net.*;
import java.nio.channels.*;


public class MyNioServer {
  public static void main(String[] params) throws Exception {
    final ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(true);
    serverChannel.socket().bind(new InetSocketAddress("localhost", 12345));
    System.out.println("Listening for incoming connections");
    final SocketChannel clientChannel = serverChannel.accept();
    System.out.println("Accepted connection: " + clientChannel);


    final Selector selector = Selector.open();
    clientChannel.configureBlocking(false);
    final SelectionKey clientKey = clientChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
    System.out.println("Selecting...");
    System.out.println(selector.select());
    System.out.println(selector.selectedKeys().size());
    System.out.println(clientKey.readyOps());
  }
}

在上述服务器收到连接之后,连接select()上的第一个服务器在没有阻塞的情况下退出,并且没有准备好操作的密钥.我不知道为什么Java会以这种方式表现,但似乎很多人都被这种行为所困扰.

Windows XP上Sun的JVM 1.5.0_06以及Linux 2.6上的Sun的JVM 1.5.0_05和1.4.2_04的结果是相同的.



2> user207421..:

原因是,OP_CONNECT并且OP_WRITE在引擎盖下是相同的东西,所以你永远不应该同时注册(同上OP_ACCEPTOP_READ),并且OP_CONNECT当频道已经连接时你根本不应该注册,因为在这种情况下,被接受了.

并且OP_WRITE几乎总是准备就绪,除非e内核中的套接字发送缓冲区已满,所以你只应在获得零长度写入后注册它.因此,通过注册已连接的通道,OP_CONNECT,您实际上正在注册OP_WRITE,已准备就绪,因此select()被触发.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有