2014-10-19 157 views
0

我想确定端口是否打开。为什么selector.select()总是返回0

InetSocketAddress address = new InetSocketAddress("www.google.com", 80); 
Selector selector = Selector.open(); 
SocketChannel socketChannel = SocketChannel.open(); 
socketChannel.configureBlocking(false); 
socketChannel.connect(address); 
socketChannel.register(selector, SelectionKey.OP_WRITE); 
int result = selector.select(); 
System.out.println(result); 

如果该端口未打开,觉得我看起来同样它返回0, 但是当端口是开放的,它也返回0,我希望它可以返回1.

+0

不知道这件事情,但可能是因为你指定了configureBlocking(false) - 这是否意味着操作是异步的,你不知道它何时结束? – RenniePet 2014-10-19 12:20:00

+0

我认为执行此代码时会返回1,因为写入通道已准备就绪,但它返回0,所以我很困惑。@ RenniePet – firebroo 2014-10-19 12:30:40

+0

为什么其他答案被删除? – firebroo 2014-10-19 23:13:45

回答

1

这是因为你'选择错误的事件。您应该已经注册了频道OP_CONNECT.然后,当您得到它时,请致电finishConnect(),如果它返回真正取消注册OP_CONNECT并注册您在下一个感兴趣的事件,即OP_READOP_WRITE

请注意,如果finishConnect()返回false您应该继续选择,如果它引发异常连接失败,您应该关闭通道。

如果您想要避免所有这些复杂情况,那么在处于阻塞模式时进行连接通常会更简单,然后将通道置于非阻塞模式并进行选择。

尽管在客户端中使用NIO确实没有什么意义。

请参阅here这个答案的更全面的版本。

+0

当我使用 socketChannel.register(selector,SelectionKey.OP_CONNECT); int result = selector.select(); System.out.println(result); 它总是返回1端口是否打开,所以当端口关闭时什么事件准备好了?为什么它也返回1. @ EJP – firebroo 2014-10-20 00:11:25

+0

因为它希望你调用'finishConnect()',如上所述。所以那样做。然后你会得到真,假或者异常。 – EJP 2014-10-20 01:09:15