2013-09-27 58 views
4

我有一個android應用程序需要通過協議UDP每100毫秒發送一次數據。每個UDP數據包平均有15000字節。數據包以廣播形式發送按順序發送大型UDP數據包的最佳方法

下面的每個100毫秒的行都通過循環運行。

DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 9876); 
clientSocket.send(sendPacket); 

應用程序啓動時工作正常,但之後收到的數據包約1分鐘的頻率減小,直到數據包不會在到達目的地。

理論極限(在Windows上)對於UDP數據包的最大尺寸爲65507個字節

我知道網絡的媒體MTU是1500個字節,當我發送一個數據包越大它被分解成幾個片段如果一個片段沒有到達目的地,那麼整個包就會丟失。

我不明白爲什麼最初1分鐘的數據包發送正確,過了一段時間數據包不會到達更多。所以我想知道解決這個問題最好的辦法是什麼?

+0

BTW碎片也可能無序到達。 ;) –

+1

我認爲TCP不是一個選項? –

+0

我正在發送圖片,如果我失去了一些30%的數據包不會成爲問題。在這種情況下,tcp較慢並不是一個好主意。我的問題是所有數據包在一段時間後都會丟失。謝謝 –

回答

10

這正是你所描述的問題。您廣播的每個數據報被分成44個數據包。如果其中任何一個丟失,數據報將丟失。只要有足夠的流量導致1%的數據包丟失,就會有35%的數據報丟失。 2%的數據包丟失等於60%的數據報丟失。

你需要保持你的廣播數據報足夠小,不要碎片。如果你有一個65,507字節的數據流,這樣你就不能改變你必須讓整個數據塊有用的事實,那麼天真的UDP廣播是不好的的選擇。

我必須知道更多關於應用程序的具體信息才能提出明智的建議。但是,如果你有大約64KB的大量數據,這樣你需要整個數據塊纔能有用,而且你不能改變它,那麼你應該使用一種方法,將數據分成若干冗餘,一些碎片可能會丟失。通過erasure coding,您可以將65,507個字節的數據分成46個塊,每個塊包含1,490個字節,這樣原始數據就可以從任意44個塊中重新構建。這將容忍中等數據報丟失,數據大小隻增加約4%。

+0

(對於OP)一個選項是將UDP消息拆分爲幾個較小的UDP消息,因此如果丟失一個數據包,則只有一小部分數據丟失。當然,這意味着您可能需要一種機制來在接收方「重建」原始消息,這可能會要求重複丟失數據報。在UDP上有效地實現(類似)TCP。 – SJuan76

+0

並非如此不尋常,實際上這就是OpenVPN的工作原理。 – SJuan76

+0

我有一個android應用程序,它使用opencv分析來自攝像頭的幀並通過UDP將這些幀發送到另一個設備。我會嘗試壓縮更多的幀並將其分成冗餘的圖表,然後研究擦除代碼。謝謝你的提示。我只是不明白爲什麼平均1分鐘執行後會有更大的包丟失。 –

2

當您需要可靠和正確的訂購交貨時,TCP專門用於代替UDP。但是,假設你真的需要UDP廣播,你可以:

  1. 調試網絡,看看如何&,其中包丟失,或者它是堵塞/滯後的接收器。但是你經常無法控制這些東西。是否涉及WiFi網絡?如果是這樣,很難獲得良好的QoS。

  2. 在應用層上做些什麼來確保訂購和可靠的交付。例如,SIP通常使用UDP,但該協議使用事務和序列號,因此客戶端將根據需要重新傳輸消息。

  3. 實現丟包隱藏。使用數學方法,接收器可以重新創建丟失的數據包,類似於RAID磁盤設置如何丟失驅動器並仍能正常工作。

您的設置可以正常工作一分鐘,然後不會暗示廣播或接收端有網絡擁塞或軟件擁塞。

你可以用Wireshark做一些數據包捕獲並分享結果嗎?

+0

我不知道Wireshark。我會讀一讀。我沒有想過要在網絡上進行調試。對我來說可能是一個好主意,可以瞭解正在發生的事情並瞭解更多信息。謝謝你的提示。 –

+0

我只是選擇UDP,因爲我的應用程序發送一系列圖像,每個包一個圖像,並且應用程序丟失了一些沒有問題的包。我希望傳輸儘可能快,所以我選擇了UDP。數據通過使用WIFI的專用網絡傳輸。 –