2009-02-20 159 views
14

NIO中的非阻塞TCP/IP SocketChannel和Selector帮助我处理很多具有少量线程的TCP/IP连接。但是UDP DatagramChannel怎么样? (我必须承认,我对UDP不是很熟悉。)非阻塞UDP I/O vs阻塞Java中的UDP I/O

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

如果DatagramSocket.send(DatagramPacket)实际上没有阻塞,并且我不打算使用连接的DatagramSocket并只绑定到一个端口,那么在DatagramChannel和Selector中使用非阻塞模式没有优势吗?

回答

12

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

UDP协议并不像TCP那样建立连接。相反,它只是发送数据并忘记它。如果确保数据真正到达那里非常重要,那么这就是客户的责任。因此,即使您处于阻止模式,只要将缓冲区清空即可,发送操作只会阻塞。由于UDP不知道有关网络的任何信息,因此它会尽早将它写出来,而不检查网络速度,或者它是否真的到达了应该发生的地方。因此,对你来说,似乎该频道实际上已经准备好进行更多发送。

+1

如果内核缓冲区被UDP套接字上的太快写入导致会发生什么? – trustin 2009-02-20 14:00:52

8

UDP不会阻塞(它只在将数据传输到操作系统时阻塞) 这意味着,如果在任何时候下一跳/交换机/机器都不能缓冲UDP数据包,则会丢弃它。在某些情况下,这可能是理想的行为。但这是你需要注意的事情。

UDP也不能保证在它们被发送的顺序

  • 分组传输。
  • 不打破大包。
  • 跨交换机转发数据包。通常在交换机之间的UDP转发关闭。

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

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

0

非阻塞UDP在接收端最为有用。 数据包发送只能因当地情况而延迟:本地流量整形工具(如“游戏网卡”)会优先于其他流量来源的游戏流量,或者网卡过载(这种情况不太可能发生)会延迟发送数据包。一旦离开系统。一旦数据包离开本地界面,它不再是应用程序的问题。