12

NIO 和 TCP 非常适合许多连接。由于需要为每个新客户端打开一个新连接,因此这些客户端中的每一个通常都需要自己的线程来阻塞 I/O 操作。NIO 解决了这个问题,它允许在可以读取数据时读取数据,而不是在数据可用之前阻塞。但是UDP呢?

我的意思是,无连接 UDP 不具有与之关联的 TCP 的阻塞特性,因为协议是如何设计的(基本上发送它并忘记它)。如果我决定将一些数据发送到某个地址,那么它会这样做,没有延迟(在服务器端)。同样,如果我想读取数据,我可以只接收来自不同来源的单个数据包。我不需要使用许多线程与许多地方建立很多连接来处理它们中的每一个。

那么,NIO 和选择器是如何增强 UDP 的呢?更具体地说,什么时候更愿意将 UDP 与 NIO 一起使用而不是 ol'java.net包?

4

2 回答 2

9

那么该DatagramSocket.receive(...)方法被记录为阻塞操作。因此,例如,如果您有一个线程试图处理来自 N 个不同套接字的数据包,您将需要使用 NIO 和选择器。类似地,如果线程必须将新数据包与其他活动进行多路复用检查,您可能会这样做。

如果您没有这些或类似的要求,那么选择器将无济于事。但这与 TCP 案例没有什么不同。如果不需要,则不应将选择器与 TCP 一起使用,因为它可能会添加额外的系统调用。

(在 Linux 上,在数据报的情况下,你会做一个select系统调用,后跟一个recv... 而不仅仅是一个recv。)


但是,如果您只处理一个 DatagramSocket,那么接收方法不会在数据包到达时立即读取数据包,而不管它们来自不同的计算机吗?

如果您正在一个套接字上侦听来自“每个人”的数据报,那么可以。如果您有不同的插座用于不同的计算机,那么没有。

对于 TCP 注释,有时使用选择器的理由很简单,因为拥有数千个线程对资源的要求很高,因为阻塞的 TCP 服务器需要它。

我们不是在讨论那个案子。但是,是的,这是真的。如果您有数千个线程阻塞 UDP 接收,情况也是如此。

我的观点是,如果您没有很多线程,或者如果线程阻塞无关紧要,那么 NIO 就无济于事。事实上,它可能会降低性能。

于 2013-04-16T23:05:33.843 回答
4

NIO 完全消除了线程的必要性。它使您可以在一个线程中处理所有客户端,包括 TCP 和 UDP 客户端。

无连接 UDP 没有与之关联的 TCP 的阻塞特性

这不是真的。接收仍然阻塞,发送也可以,至少在理论上是这样。

于 2013-04-17T00:05:24.010 回答