非阻塞 UDP I/O 与在 Java 中阻止 UDP I/O

2022-09-02 21:11:35

非阻塞 TCP/IP 和 NIO 可帮助我处理具有少量线程的许多 TCP/IP 连接。但是UDP怎么样?(我必须承认,我对UDP不是很熟悉。SocketChannelSelectorDatagramChannels

UDP 发送操作似乎不会阻塞,即使 未在阻塞模式下运行也是如此。是否真的存在由于拥堵或类似原因而阻塞的情况?我真的很好奇是否有这种情况,以及生产环境中可能存在什么情况。DatagramChannelDatagramSocket.send(DatagramPacket)

如果实际上没有阻塞,并且我不打算使用连接并仅绑定到一个端口,那么使用带有和的非阻塞模式没有好处吗?DatagramSocket.send(DatagramPacket)DatagramSocketDatagramChannelSelector


答案 1

我已经有一段时间没有使用Java的DatagramSockets,Channels等了,但我仍然可以给你一些帮助。

UDP 协议不会像 TCP 那样建立连接。相反,它只是发送数据并忘记它。如果重要的是要确保数据真正到达那里,那就是客户的责任。因此,即使您处于阻塞模式,发送操作也只会阻塞,只要将缓冲区冲出即可。由于UDP对网络一无所知,因此它将尽早将其写出,而无需检查网络速度或是否实际到达了它应该要去的地方。因此,对您来说,该通道似乎实际上已立即准备好进行更多发送。


答案 2

UDP 不会阻塞(它只在将数据传输到操作系统时阻止)这意味着,如果在任何时候下一个跃点/交换机/计算机无法缓冲 UDP 数据包,它会丢弃它。在某些情况下,这可能是可取的行为。但这是你需要注意的。

UDP也不能保证

  • 按发送顺序传送数据包。
  • 不要分解大包。
  • 跨交换机转发数据包。交换机之间的 UDP 转发通常处于关闭状态。

但是,UDP 确实支持多播,因此可以将相同的数据包传送到一个或多个主机。但是,发送方不知道是否有人收到数据包。

关于UDP的一个棘手问题是它大部分时间都有效,但有时会以非常难以重现的方式严重失败。出于这个原因,即使您做了一些测试并且它似乎有效,也不应该假设可靠性。


推荐