UDP丟包和無序 問題的解決方法

2022-03-27 10:32:55 字數 2545 閱讀 2380

最近在做乙個專案,在這之前,做了個驗證程式. 

發現客戶端連續發來1000個1024位元組的包,伺服器端出現了丟包現象. 

糾其原因,是服務端在還未完全處理掉資料,客戶端已經資料傳送完畢且關閉了. 

我用過sleep(10),暫時解決這個問題,但是這不是根本解決辦法,如果資料量大而多,網路情況不太好的話,還是有可能丟失.

你試著用阻塞模式吧... 

select...我開始的時候好像也遇到過..不過改為阻塞模式後就沒這個問題了...

採用回包機制,每個發包必須收到回包後再發下乙個

udp丟包是正常現象,因為它是不安全的。

丟包的原因我想並不是「服務端在還未完全處理掉資料,客戶端已經資料傳送完畢且關閉了」,而是伺服器端的socket接收快取滿了(udp沒有流量控制,因此傳送速度比接收速度快,很容易出現這種情況),然後系統就會將後來收到的包丟棄。你可以嘗試用setsockopt()將接收快取(so_rcvbuf)加大看看能不能解決問題。

服務端採用多執行緒pthread接包處理

udp是無連線的,面向訊息的資料傳輸協議,與tcp相比,有兩個致命的缺點,一是資料報容易丟失,二是資料報無序。 

要實現檔案的可靠傳輸,就必須在上層對資料丟包和亂序作特殊處理,必須要有要有丟包重發機制和超時機制。 

常見的可靠傳輸演算法有模擬tcp協議,重發請求(arq)協議,它又可分為連續arq協議、選擇重發arq協議、滑動視窗協議等等。 

如果只是小規模程式,也可以自己實現丟包處理,原理基本上就是給檔案分塊,每個資料報的頭部新增乙個唯一標識序號的id值,當接收的包頭部id不是期望中的id號,則判定丟包,將丟包id發回服務端,伺服器端接到丟包響應則重發丟失的資料報。 

模擬tcp協議也相對簡單,3次握手的思想對丟包處理很有幫助。

udp是不安全的,如果不加任何控制,不僅會丟失包,還可能收到包的順序和傳送包的順序不一樣。這個必須在自己程式中加以控制才行。 

收到包後,要返回乙個應答,如果傳送端在一定時間內沒有收到應答,則要重發。

udp本來存在丟包現象,現在的解決方案暫時考慮雙方增加握手. 

這樣做起來,就是udp協議裡面加上了tcp的實現方法. 

程式中採用的是pthread處理,丟包率時大時小,不穩定可靠

我感覺原因可能有兩個,乙個是客戶端傳送過快,網路狀況不好或者超過伺服器接收速度,就會丟包。 

第二個原因是伺服器收到包後,還要進行一些處理,而這段時間客戶端傳送的包沒有去收,造成丟包。

解決方法,

一是   客戶端降低傳送速度,可以等待回包,或者加一些延遲。 

二是,伺服器部分單獨開乙個執行緒,去接收udp資料,存放在乙個緩衝區中,又另外的執行緒去處理收到的資料,儘量減少因為處理資料延時造成的丟包。

有兩種方法解決樓主的問題: 

方法一:重新設計一下協議,增加接收確認超時重發。(推薦) 

方法二:在接收方,將通訊和處理分開,增加個應用緩衝區;如果有需要增加接收socket的系統緩衝區。(本方法不能從根本解決問題,只能改善)

網路丟包,是再正常不過的了。 

既然用udp,就要接受丟包的現實,否則請用tcp。 

如果必須使用udp,而且丟包又是不能接受的,只好自己實現確認和重傳,說白了,就是自己實現tcp(當然是部分和有限的簡單實現)。

udp是而向無連線的,使用者在實施udp程式設計時,必須制定上層的協議,包括流控制,簡單的超時和重傳機制,如果不要求是實時資料,我想tcp可能會更適合你!

huangcanbao 發表於tuesday, september 22, 2009 7:33:22 pm 舉報

今天接到了**面試,還好我的解決方案和你這位朋友的一樣。1:給自己發的資料定義協議,序號 大小 資料。 2:傳輸過程都要進行雙方驗證,是否接受到正確的資料。根據傳輸的位元組大小來管理的。

**建議的辦法是,對於大的報文自己進行乙個分包和組包操作.要減少丟包率(丟包重發,同樣是不小的消耗),把單包的大小定在1500位元組以內,按24mbit/s的頻寬最大流通量2048個包每秒,這個壓力是相當小的.

丟包是很正常的,發包越大丟包的可能性就越高,與網絡卡速度沒有必然聯絡,需要自己設計應答和重發機制。至於多大的資料報最合適,要在實際執行的環境中測試才能知道。程式執行過程中可以自己統計並計算丟包率,然後動態調整資料報的大小來適應執行環境。

另外是記憶體池這些,最簡單的,你要是每次new char[1024]再去收,那收執行緒速度就當下來了. 

記住,收執行緒不要做任何事.那怕只查個map,在上萬包每秒時,每秒的操作就上萬個map查詢, 

另外丟包可能是傳送端,發出來已經丟了,你要考慮傳送的的傳送處理,傳送處理寫得不好,其實發 

的過程根本沒機會出網絡卡緩衝,就已經丟了有可能. 

中間路由器環節(這個無法控制,只能看看這個環節效能如何)

UDP丟包及無序的問題

最近在做乙個專案,在這之前,做了個驗證程式.發現客戶端連續發來1000個1024位元組的包,伺服器端出現了丟包現象.糾其原因,是服務端在還未完全處理掉資料,客戶端已經資料傳送完畢且關閉了.有沒有成熟的解決方案來解決這個問題.我用過sleep 1 暫時解決這個問題,但是這不是根本解決辦法,如果資料量大...

UDP丟包及無序的現象

發現客戶端連續發來1000個1024位元組的包,伺服器端出現了丟包現象.糾其原因,是服務端在還未完全處理掉資料,客戶端已經資料傳送完畢且關閉了.有沒有成熟的解決方案來解決這個問題.我用過sleep 1 暫時解決這個問題,但是這不是根本解決辦法,如果資料量大而多,網路情況不太好的話,還是有可能丟失.你...

tcpdump丟包問題解決方法

近日用tcpdump抓包,發現有大量的丟包出現 packets dropped by kernel 如下 tcpdump i eth0 dst port 1234 and udp s 2048 x tt a.pack 264 packets captured 3043 packets receive...