2009-02-20 157 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在接收端最爲有用。 數據包發送只能因當地情況而延遲:本地流量整形工具(如「遊戲網卡」)會優先於其他流量來源的遊戲流量,或者網卡過載(這種情況不太可能發生)會延遲發送數據包。一旦離開系統。一旦數據包離開本地界面,它不再是應用程序的問題。