丟包檢查方法
- 給每個(gè)UDP包編號(hào)恳谎,對(duì)比收發(fā)端的接收到的包。對(duì)于UDP協(xié)議層上的包瓢对,例如RTP包寿酌,可以從RTP包中讀出包的序列號(hào)進(jìn)行判斷。
- 抓包硕蛹。發(fā)送端和接收端分別抓包醇疼。linux下可以使用tcpdump,windows下使用wireshark法焰。
- linux下秧荆,可以使用watch netstat -su查看丟包統(tǒng)計(jì)。主要看RcvbufErrors和SndbufErrors埃仪。如果兩個(gè)統(tǒng)計(jì)項(xiàng)的數(shù)字都在不斷增加乙濒,表明網(wǎng)卡有丟包。
發(fā)送方丟包
發(fā)送的包太大
發(fā)送的包比64K大會(huì)導(dǎo)致UDP協(xié)議sendto返回錯(cuò)誤卵蛉。
發(fā)送的包比MTU大琉兜,UDP包在接收端容易丟包,可查看接收端的網(wǎng)卡統(tǒng)計(jì)毙玻⊥泱可考慮把包切分到MTU一下再發(fā)送。
發(fā)包速度太快
發(fā)包速度太快的話桑滩,可能有兩個(gè)問題:1.接收端來不及接收導(dǎo)致接收端丟包梧疲。2.發(fā)送端網(wǎng)卡處理不過來。這個(gè)時(shí)候sendto沒有返回錯(cuò)誤运准,但是用netstat查看會(huì)發(fā)現(xiàn)SndbufErrors不斷上升幌氮,有可能是網(wǎng)卡的輸出隊(duì)列太小導(dǎo)致⌒舶模可以考慮使用ifconfig命令把txqueuelen設(shè)置大一些该互。
UDP包流量太大
同一個(gè)端口發(fā)送的數(shù)據(jù)量太大時(shí)會(huì)導(dǎo)致網(wǎng)卡丟包,這個(gè)時(shí)候可以用netstat查看會(huì)發(fā)現(xiàn)SndbufErrors不斷上升韭畸。sendto會(huì)返回-1.這個(gè)時(shí)候可以考慮增大/proc/sys/net/core/wmem_max的值宇智。
這種情況尤其是同時(shí)給多個(gè)客戶端發(fā)送音視頻數(shù)據(jù)時(shí)導(dǎo)致。筆者曾經(jīng)遇到過這么一次情況胰丁。一個(gè)端口向8個(gè)客戶端發(fā)送視頻流時(shí)随橘,網(wǎng)卡流量大概400M/s,sendto會(huì)返回-1锦庸,errno 11.程序里也調(diào)用setsockopt設(shè)置了發(fā)送緩沖區(qū)為60M机蔗,然而還是會(huì)丟包。后來將系統(tǒng)參數(shù)/proc/sys/net/core/wmem_max設(shè)到60M才解決問題。
接收端丟包
接收緩沖區(qū)太小
接收緩沖區(qū)小于發(fā)送客戶端的包的大小萝嘁,或者接收客戶端recvfrom速度太慢梆掸,導(dǎo)致接收緩沖區(qū)滿丟棄數(shù)據(jù)。前一種問題牙言,可以考慮增大接收緩沖區(qū)沥潭。后一種問題,可以考慮將接收操作和業(yè)務(wù)處理操作分離到不同的線程來處理嬉挡。