Java 中的非阻塞 UDP I/O 与阻塞 UDP I/O
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/569555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Non-blocking UDP I/O vs blocking UDP I/O in Java
提问by trustin
Non-blocking TCP/IP SocketChannels and Selectorin NIO help me to handle many TCP/IP connections with small number of threads. But how about UDP DatagramChannels? (I must admit that I'm not very familiar with UDP.)
非阻塞 TCP/IPSocketChannel和SelectorNIO 帮助我用少量线程处理许多 TCP/IP 连接。但是 UDPDatagramChannels呢?(我必须承认我对 UDP 不是很熟悉。)
UDP send operations don't seem to block even if the DatagramChannelis not operating in blocking mode. Is there really a case where DatagramSocket.send(DatagramPacket)blocks due to congestion or something similar? I'm really curious if there's such a case and what the possible cases exist in a production environment.
即使DatagramChannel未在阻塞模式下运行,UDP 发送操作似乎也不会阻塞。是否真的存在DatagramSocket.send(DatagramPacket)由于拥塞或类似原因导致阻塞的情况?我真的很好奇是否存在这种情况以及生产环境中可能存在的情况。
If DatagramSocket.send(DatagramPacket)doesn't actually block and I am not going to use a connected DatagramSocketand bind to only one port, is there no advantage of using non-blocking mode with DatagramChanneland Selector?
如果DatagramSocket.send(DatagramPacket)实际上没有阻止,我不打算使用一个连接DatagramSocket并绑定到只有一个端口,有没有使用非阻塞模式的优势DatagramChannel和Selector?
采纳答案by James
It's been a while since I've used Java's DatagramSockets, Channels and the like, but I can still give you some help.
我已经有一段时间没有使用 Java 的 DatagramSockets、Channels 之类的了,但我仍然可以给你一些帮助。
The UDP protocol does not establish a connection like TCP does. Rather, it just sends the data and forgets about it. If it is important to make sure that the data actually gets there, that is the client's responsibility. Thus, even if you are in blocking mode, your send operation will only block for as long as it takes to flush the buffer out. Since UDP does not know anything about the network, it will write it out at the earliest opportunity without checking the network speed or if it actually gets to where it is supposed to be going. Thus, to you, it appears as if the channel is actually immediately ready for more sending.
UDP 协议不像 TCP 那样建立连接。相反,它只是发送数据并忘记它。如果确保数据真正到达那里很重要,那就是客户的责任。因此,即使您处于阻塞模式,您的发送操作也只会在刷新缓冲区所需的时间内阻塞。由于 UDP 对网络一无所知,它会在不检查网络速度或它是否真的到达它应该去的地方的情况下尽早将它写出来。因此,对您而言,似乎频道实际上已准备好进行更多发送。
回答by Peter Lawrey
UDP doesn't block (It only blocks while it is transferring the data to the OS) This means if at any point the next hop/switch/machine cannot buffer the UDP packet it drops it. This can be desirable behaviour in some situations. But it is something you need to be aware of.
UDP 不会阻塞(它只会在将数据传输到操作系统时阻塞)这意味着如果下一跳/交换机/机器在任何时候都无法缓冲它丢弃的 UDP 数据包。在某些情况下,这可能是理想的行为。但这是您需要注意的事情。
UDP also doesn't guarantee to
UDP 也不保证
- delivery packets in the order they are sent.
- not to break up large packets.
- forward packets across switches. Often UDP forwarding between switches is turned off.
- 按发送顺序发送数据包。
- 不要分解大数据包。
- 跨交换机转发数据包。通常,交换机之间的 UDP 转发是关闭的。
However UDP does support multicast so the same packet can be delivered to one or more hosts. The sender has no idea if anyone receives the packets however.
但是 UDP 确实支持多播,因此可以将相同的数据包传送到一台或多台主机。但是,发送方不知道是否有人收到了数据包。
A tricky thing about UDP is it works most of the time, but fails badly sometimes in ways which are very difficult to reproduce. For this reason, you shouldn't assume reliability even if you do a few tests and it appears to work.
UDP 的一个棘手之处在于它大部分时间都可以工作,但有时会以难以重现的方式严重失败。出于这个原因,即使您进行了一些测试并且它似乎有效,您也不应该假设可靠性。
回答by Andras Balázs Lajtha
Non blocking UDP is mostly useful on the receiving side. Packet sending can only be delayed due to local circumstances: local traffic shaping tools like "gaming network cards" that prioritize gaming traffic over other traffic sources, or overloaded network card (which is not likely to happen) can delay the sending of a packet. Once out of the system. Once the packet leaves the local interface, it's no longer the application's concern.
非阻塞 UDP 在接收端最有用。数据包发送只能因本地情况而延迟:本地流量整形工具,如“游戏网卡”将游戏流量优先于其他流量源,或网卡过载(不太可能发生)可能会延迟数据包的发送。一旦退出系统。一旦数据包离开本地接口,它就不再是应用程序的关注点。

