2013-04-16 41 views
8

NIO和TCP使許多連接成爲一對。由於需要爲每個新客戶端打開一個新連接,因此每個客戶端通常都需要自己的線程來阻止I/O操作。 NIO通過允許數據在可能時被讀取來解決該問題,而不是在可用之前阻塞。但是UDP呢?在NIO中使用UDP有什麼意義?

我的意思是,無連接的UDP沒有與之相關的TCP阻塞性質,因爲協議設計的方式(基本上是發送它並將其忘掉)。如果我決定發送一些數據到某個地址,那麼它會這樣做,沒有延遲(在服務器端)。同樣,如果我想讀取數據,我只能接收來自不同來源的單個數據包。我不需要使用許多線程來處理它們中的每一個,就可以有很多連接到很多地方。

那麼,NIO和選擇器如何增強UDP?更具體地說,何時會更喜歡使用UDP與NIO而不是ol'java.net包?

+0

不是你的問題的答案 - 但你應該首先檢查NIO是否更快或更好,即使是TCP - http://mailinator.blogspot.in/2008/02/kill-myth-please-nio-is-not -faster-than.html http://paultyma.blogspot.in/2008/03/writing-java-multithreaded-servers.html – user93353

回答

8

那麼DatagramSocket.receive(...)方法記錄爲阻止操作。因此,舉例來說,如果您有一個線程試圖處理來自N個不同套接字的數據包,則需要使用NIO和選擇器。同樣,如果線程必須多路複用檢查新數據包與其他活動,您可能會這樣做。

如果您沒有這些或類似的要求,那麼選擇器將無濟於事。但這與TCP案例沒有什麼不同。如果你不需要它們,你不應該使用帶有TCP的選擇器,因爲潛在的會增加額外的系統調用。

(在Linux上,在數據報的情況下,你會做一個系統調用select後跟一個recv ...而不是僅僅一個recv。)


但如果你只處理使用一個DatagramSocket,無論接收方法是否來自不同的計算機,接收方法都不會立即讀取數據包嗎?

如果你正在一個套接字上收聽來自「everyone」的數據報,那麼是的。如果你對不同的計算機有不同的套接字,那麼不需要。

而對於TCP評論,有時使用選擇器是有道理的,因爲它有非常資源的要求,有成千上萬的線程,這是阻塞TCP服務器所要求的。

我們沒有討論這種情況。但是,是的,那是真的。如果您有數千個線程阻塞UDP接收,情況也是如此。

我的觀點是,這你有大量的線程,或者如果它不要緊如果一個線程塊,然後NIO於事無補。事實上,它可能會降低性能。

+0

但是,如果你只處理一個DatagramSocket,那麼'receive'方法不會被讀取不管它們來自不同的計算機,它們都會立即到達,而不管它們是來自不同的計算機嗎而對於TCP評論,有時使用選擇器的理由很簡單,因爲它擁有數千個線程是非常需要資源的,因爲阻塞的TCP服務器會需要它。 –

+0

@MartinTuskevicius *他們何時到達*。這仍然是一個阻塞操作。通過select()循環將調度從操作系統轉移到應用程序也是非常需要資源的,而且不一定公平。你需要記住select()是在線程已經存在之前設計的,替代方案是多個*進程。 – EJP

+0

因此,如果我在多個客戶端使用的服務器端有單個UDP套接字,那麼使用阻塞IO和專用線程池來處理數據包會更高效? – ka4eli

3

NIO完全消除了線程的必要性。它允許您在一個線程中處理所有客戶端,包括TCP和UDP客戶端。

連接的UDP不具有TCP與它

這是不正確相關聯的阻擋性質。至少在理論上,接收仍然阻塞,因此可以發送。

相關問題