2013-03-18 60 views
0

大家好日子!
我正在開發Java UDP服務器。由於接收緩衝區較小,我向服務器發送大量數據並丟失部分傳入數據包。現在我以這種方式設置接收緩衝區 -以編程方式增加UDP緩衝區 - 它有意義嗎?

DatagramChannel serverChannel;
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB


它有道理嗎?該代碼沒有解決數據包丟失的問題。我的操作系統 - 64位窗口7.

還有一個問題 - 我的網絡控制器的接收緩衝區屬性默認是512 - 是字節還是兆字節?是否有必要手動增加此屬性,如果它是512 字節?我認爲增加緩衝區編程實際上增加了操作系統緩衝區,但這沒有意義,因爲最初udp數據包「來」到我的網卡。

+2

UDP協議不保證數據包傳遞。如果您不想丟失數據包,請切換到TCP或增加您發送的數量。 – Makoto 2013-03-18 03:38:48

回答

2

我發送了很多數據到我的服務器,並且由於接收緩衝區的大小很小而丟失了一部分數據包。

你不知道。有很多可能的原因。

現在我收到的設置緩衝在這樣的方式 -

DatagramChannel serverChannel; 
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB 

是否有意義?

不是真的,這是一個巨大的緩衝區,操作系統可能會將它截斷爲更合理的大小。嘗試在設置後獲取選項並查看實際大小。

此代碼並沒有解決數據包丟失問題。

沒人說這會。你只是假設它。

還有一個問題 - 我的網絡控制器的接收緩衝區屬性默認是512 - 是字節還是兆字節?

除非您告訴我們您使用的是什麼網卡,否則沒有人可以回答,但您應該可以從製造商的數據中爲您自己發現。

是否有必要手動增加此屬性,如果它是512字節?

不僅沒有必要,而且是不可能的。

我認爲增加緩衝編程方式實際上增加了操作系統的緩衝區

如果你的意思是SO_RCVBUF控制套接字接收緩衝區大小,這是正確的。

,但這沒有任何意義

是它。

因爲最初udp數據包「來」到我的網卡。

並從那裏進入操作系統,並從那裏進入IP棧,並從那裏到UDP棧,並從那裏到套接字接收緩衝區。當大多數路徑MTU高達1500字節時,NIC看起來似乎不會有512字節的緩衝區,但是例如它的確有意義。你可以認爲它已經足夠了,畢竟它工作。

您的基本假設是有缺陷的。由於各種原因,UDP數據包可能會丟失:它們從來沒有發送過,它們被中間路由器丟棄,它們被分成碎片並且並非所有的碎片都送到接收器,或者接收器的接收緩衝器滿了,反過來可能是因爲它太小或者因爲接收者無法跟上發送者。只使用巨大的套接字接收器緩衝區只能解決其中一個問題。如果您需要可靠性,請使用TCP,否則執行ACK或NACK機制並重試。

+0

+1。 TCP幾乎總是答案。 – 2013-03-18 11:18:25

1

它有道理嗎?

的種類。但是,你無法做的事情可以保證UDP數據包不會丟失。 UDP是一種天生不可靠的協議。如果您的應用程序無法快速從套接字中拉出它們,或者存在網絡錯誤,則數據包將丟失。

如果你需要數據被髮送到你的服務器可靠,你應該使用TCP ...

我的網絡控制器的接收緩衝區屬性是512默認 - 是字節或兆?

我不知道,但我都不懷疑。它更可能是千字節。


我試圖增加控制器的緩衝區大小 - 操作系統說512是最大可能)

那麼,你將不能夠把它提高到10Mb的。

所以,如果沒有新的網絡錯誤,我的數據包會在我處理它們太慢時失敗。

不完全是。由於各種原因,包可能在許多地方丟失/丟失。其中一些是「正常行爲」,而不是「網絡錯誤」;例如當路由器/網橋/網關擁塞時丟包。

增加緩衝區大小看起來足以解決問題,但令人驚訝的是失敗。

其實並不奇怪。丟包可能是正常行爲;往上看。

可能我應該在一個線程中接收數據包,並在另一個線程中處理它們,即使我使用專用於開發「單線程」服務器的java NIO。

這可能有助於減少OS丟包和網絡接口。但是,最終會緩衝應用程序內存中的數據,並且這會導致更糟糕的問題...如果應用程序無法保持長期運行。

此外,它不處理因其他原因丟失/丟棄的數據包。


底線是,你將無法使用UDP實現可靠的無損傳輸。數據包丟失是不可避免的,而你正在努力避免它。

你要麼必須設計應用程序,以應付丟失數據包,或者切換到使用TCP或其他一些協議,它提供了可靠的數據傳輸。

+0

我試圖增加控制器的緩衝區大小 - 操作系統說512是最大可能的)所以,如果沒有新的網絡錯誤,我的數據包會在唯一的情況下丟失,當我處理它們太慢。增加緩衝區大小看起來足以解決問題,但令人驚訝的是失敗。可能我應該在一個線程中接收數據包,並在另一個線程中處理它們,即使我使用致力於開發「單線程」服務器的Java NIO。 – Baurzhan 2013-03-18 03:52:46

1

UDP發送/接收離散數據包;最大尺寸約65K。如果你有更多的數據要發送,你需要把它分成多個數據包。正如其他人所指出的,UDP是一種不可靠的協議。數據包可能會消失,重複或無法接收。

相關問題