UDP主要丟包原因及具體問題分析


UDP主要丟包原因及具體問題分析

一、主要丟包原因
 
1、接收端處理時間過長導致丟包:調用recv方法接收端收到數據后,處理數據花了一些時間,處理完后再次調用recv方法,在這二次調用間隔里,發過來的包可能丟失。對於這種情況可以修改接收端,將包接收后存入一個緩沖區,然后迅速返回繼續recv。
 
2、發送的包巨大丟包:雖然send方法會幫你做大包切割成小包發送的事情,但包太大也不行。例如超過50K的一個udp包,不切割直接通過send方法發送也會導致這個包丟失。這種情況需要切割成小包再逐個send。
 
3、發送的包較大,超過接受者緩存導致丟包:包超過mtu size數倍,幾個大的udp包可能會超過接收者的緩沖,導致丟包。這種情況可以設置socket接收緩沖。以前遇到過這種問題,我把接收緩沖設置成64K就解決了。
int nRecvBuf=32*1024;//設置為32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
 
4、發送的包頻率太快:雖然每個包的大小都小於mtu size 但是頻率太快,例如40多個mut size的包連續發送中間不sleep,也有可能導致丟包。這種情況也有時可以通過設置socket接收緩沖解決,但有時解決不了。所以在發送頻率過快的時候還是考慮sleep一下吧。
 
5、局域網內不丟包,公網上丟包。這個問題我也是通過切割小包並sleep發送解決的。如果流量太大,這個辦法也不靈了。總之udp丟包總是會有的,如果出現了用我的方法解決不了,還有這個幾個方法: 要么減小流量,要么換tcp協議傳輸,要么做丟包重傳的工作。
 
 
二、具體問題分析
 
1.發送頻率過高導致丟包
 
很多人會不理解發送速度過快為什么會產生丟包,原因就是UDP的SendTo不會造成線程阻塞,也就是說,UDP的SentTo不會像TCP中的SendTo那樣,直到數據完全發送才會return回調用函數,它不保證當執行下一條語句時數據是否被發送。(SendTo方法是異步的)這樣,如果要發送的數據過多或者過大,那么在緩沖區滿的那個瞬間要發送的報文就很有可能被丟失。至於對“過快”的解釋,作者這樣說:“A few packets a second are not an issue; hundreds or thousands may be an issue.”(一秒鍾幾個數據包不算什么,但是一秒鍾成百上千的數據包就不好辦了)。 要解決接收方丟包的問題很簡單,首先要保證程序執行后馬上開始監聽(如果數據包不確定什么時候發過來的話),其次,要在收到一個數據包后最短的時間內重新回到監聽狀態,其間要盡量避免復雜的操作(比較好的解決辦法是使用多線程回調機制)。
 
2.報文過大丟包
 
至於報文過大的問題,可以通過控制報文大小來解決,使得每個報文的長度小於MTU。以太網的MTU通常是1500 bytes,其他一些諸如撥號連接的網絡MTU值為1280 bytes,如果使用speaking這樣很難得到MTU的網絡,那么最好將報文長度控制在1280 bytes以下。
 
3.發送方丟包
 
發送方丟包:內部緩沖區(internal buffers)已滿,並且發送速度過快(即發送兩個報文之間的間隔過短);  接收方丟包:Socket未開始監聽;  雖然UDP的報文長度最大可以達到64 kb,但是當報文過大時,穩定性會大大減弱。這是因為當報文過大時會被分割,使得每個分割塊(翻譯可能有誤差,原文是fragmentation)的長度小於MTU,然后分別發送,並在接收方重新組合(reassemble),但是如果其中一個報文丟失,那么其他已收到的報文都無法返回給程序,也就無法得到完整的數據了。

 

-------------------------

 

UDP丟包

我們是后一個包丟掉了

 

最近在做一個項目,在這之前,做了個驗證程序.
發現客戶端連續發來1000個1024字節的包,服務器端出現了丟包現象.
糾其原因,是服務端在還未完全處理掉數據,客戶端已經數據發送完畢且關閉了.

有沒有成熟的解決方案來解決這個問題.
我用過sleep(1),暫時解決這個問題,但是這不是根本解決辦法,如果數據量大而多,網絡情況不太好的話,還是有可能丟失.

 

你試着用阻塞模式吧...
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可能會更適合你!

 

-------------------------

1:什么是丟包率? 

你的電腦向目標發送一個數據包,如果對方沒有收到.就叫丟包. 
比如你發10個,它只收到9個. 那么丟包率就是 10% 
數據在網絡中是被分成一各個個數據報傳輸的,每個數據報中有表示數據信息和提供數據路由的楨.而數據報在一般介質中傳播是總有一小部分由於兩個終端的距離過大會丟失,而大部分數據包會到達目的終端.所謂網絡丟包率是數據包丟失部分與所傳數據包總數的比值.正常傳輸時網絡丟包率應該控制在一定范圍內.

2:什么是吞吐量?
網絡中的數據是由一個個數據包組成,防火牆對每個數據包的處理要耗費資源。吞吐量是指在沒有幀丟失的情況下,設備能夠接受的最大速率。其測試方法是:在測試中以一定速率發送一定數量的幀,並計算待測設備傳輸的幀,如果發送的幀與接收的幀數量相等,那么就將發送速率提高並重新測試;如果接收幀少於發送幀則降低發送速率重新測試,直至得出最終結果。吞吐量測試結果以比特/秒或字節/秒表示。

吞吐量和報文轉發率是關系防火牆應用的主要指標,一般采用FDT(Full Duplex Throughput)來衡量,指64字節數據包的全雙工吞吐量,該指標既包括吞吐量指標也涵蓋了報文轉發率指標。 

隨着Internet的日益普及,內部網用戶訪問Internet的需求在不斷增加,一些企業也需要對外提供諸如WWW頁面瀏覽、FTP文件傳輸、DNS域名解析等服務,這些因素會導致網絡流量的急劇增加,而防火牆作為內外網之間的唯一數據通道,如果吞吐量太小,就會成為網絡瓶頸,給整個網絡的傳輸效率帶來負面影響。因此,考察防火牆的吞吐能力有助於我們更好的評價其性能表現。這也是測量防火牆性能的重要指標。

吞吐量的大小主要由防火牆內網卡,及程序算法的效率決定,尤其是程序算法,會使防火牆系統進行大量運算,通信量大打折扣。因此,大多數防火牆雖號稱100M防火牆,由於其算法依靠軟件實現,通信量遠遠沒有達到100M,實際只有10M-20M。純硬件防火牆,由於采用硬件進行運算,因此吞吐量可以達到線性90-95M,是真正的100M防火牆。

對於中小型企業來講,選擇吞吐量為百兆級的防火牆即可滿足需要,而對於電信、金融、保險等大公司大企業部門就需要采用吞吐量千兆級的防火牆產品。

3:檢測丟包率
下載一個世紀前線,在百度可以找到,很小的程序。

NetIQ Chariot  一款網絡應用軟件性能測試工具

網絡吞吐量測試,CHARIOT測試網絡吞吐量

http://wenku.baidu.com/link?url=JgKLSru8LBtaqxTIwAzJHAn-S-rhqZQgO1FQB_snRK5n3GYUFFhO9pQJs3bjyxWenH-rFv_H5qm7ke3mfcGK3MDFDO23zTf05GoLs2S7O8O


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM