在 Java NIO 中,选择器对客户端 SocketChannel 有用吗?

Posted

技术标签:

【中文标题】在 Java NIO 中,选择器对客户端 SocketChannel 有用吗?【英文标题】:In Java NIO, is a selector useful for a client SocketChannel? 【发布时间】:2012-09-02 12:34:08 【问题描述】:

在 Java NIO 中,很容易理解为什么一个 ServerSocketChannel 必须有一个选择器。选择器可以从准备好进行 I/O 操作的多个客户端通道中进行检查。

但是,在我在网上阅读的一些评论中,选择器机制应用于客户端 SocketChannel。我不明白为什么选择器对客户有用。谁能解释为什么它在只有一台服务器的通常情况下有用?

【问题讨论】:

例如页面底部的tutorials.jenkov.com/java-nio/socket-channel.html推荐选择器和SocketChannel。 但他不向客户推荐任何一种。该教程中有很多不好的建议:例如在非阻塞模式下循环。找一个更好的。 【参考方案1】:

选择器让您可以使用单个线程跨多个通道进行并发通信。当您必须同时与多个服务器进行通信时,或者当您以客户端角色与对等计算机进行通信时(例如读取种子文件时),它可能在客户端上很有用。

【讨论】:

感谢您的回答。我还想贡献一点,客户端的选择器对于客户端和服务器之间相互交换 SelectionKey 显然是必要的。你同意还是不同意? @Arvanem 我不会说它们是“必要的”,因为您可以使用两个线程来做同样的事情。然而选择器确实很方便,让您可以编写单线程代码来处理并发任务。 但是如果您的服务器套接字通道正在使用选择器,这是必要的,对吧?因为除了允许您将 SelectionKey 触发回服务器的选择器之外别无他法? @Arvanem 没有诸如“客户端和服务器之间相互交换 SelectionKeys”或“在服务器端返回 [ing] SelectionKeys”这样的事情。这些问题毫无意义。您不必在 TCP 连接的两端都使用 NIO,如果这就是您所理解的。 TCP就是TCP,但它是在应用程序中实现的。 “选择器和选择键在内部运行”。正确的。所发生的一切都是由读缓冲区变为非空(包括 FIN)或写缓冲区变为非满来触发 Selector 事件。它与网络或对等点或连接无关。【参考方案2】:

除非您连接到数百台服务器,否则很难在客户端中看到非阻塞 NIO 的意义。但是如果你使用的是非阻塞NIO,你肯定要使用Selector,否则你不知道什么时候读取通道,或者写入不完整后什么时候再次变为可写。

【讨论】:

以上是关于在 Java NIO 中,选择器对客户端 SocketChannel 有用吗?的主要内容,如果未能解决你的问题,请参考以下文章

3.NIO选择器(基于NIO的服务器与客户端通讯)

java之NIO编程

java之NIO编程

转载NIO客户端序列图

NIO Selector(选择器)

java中NIO的selector