記錄一個UDP收包丟包的問題


這幾天寫GB28181平台接入層代碼,對收到的PS包進行解包時,總是出現誤碼,最終導致rtsp點播服務中畫面花屏。

分析了碼流抓包數據之后,發現網絡上沒有丟包,遂認為PS流解包代碼有bug,於是埋頭分析了2個小時的解包函數后,沒有發現問題。將抓包RTP負載中的PS包數據導出之后,專門利用PS解包代碼寫了一個小程序,對導出的數據進行處理,又沒有問題——后來事實證明解包代碼的確沒有問題,而且這部分的代碼是在其他項目中用過的。自己有些迷糊了,一時想不明白問題出在哪里。

冷靜后分析一下,認為抓包結果中的數據不代表應用實際所接收到的數據,二者之間應該是有差別的,比如數據順序可能會不一樣。遂在收包入口函數中,打印每個收到的RTP包的序號,根據序號終於發現:順序沒有亂,但是不間斷的有包丟了。這可是問題了,媒體數據是直接進行PS包封裝后再在RTP上傳輸的,丟了少量的包,會導致整個PS包都難以恢復。好在已經知問題是因為收包丟包導致的,現在又繼續分析收包丟包的原因。

問題具體情況是采用UDP承載RTP包,RTP包負載部分是PS格式封包的H264碼流,每收到一個RTP包,應用就立即對負載中的PS流進行嘗試解包(包括必需的緩沖操作),處理完一個RTP包之后再回頭繼續收包。這樣就導致了每次收包之間,間隔比較明顯了。用“UDP收包 丟包”作為關鍵字在網上搜索了一些之后,了解到

采用UDP進行數據通信,若實際流量較大,但recv buffer又不夠大,且沒有及時進行收包時,則容易造成recv buffer滿而丟包

自己業務是用UDP來接收高清視頻碼流,流量是不小的,並且自己的實現也的確容易導致沒有及時收包,覺得上述說法可能是原因。立馬進行修改驗證,先將recv buffer增加2MiB,花屏現象消失,根據接收的RTP包的序號確認,現在應用層收到的RTP包沒有丟包。

到此接入的問題似乎是已經已經解決了,但現在回頭看UDP收包的問題,覺得簡單擴大recv buffer不是根本之道,只是在本業務場景中,擴大recv buffer后,新增出的buffer尺寸對應的容量,大於視頻媒體數據流量,因而沒有使得buffer滿而丟包。UDP收包丟包,根本上還是需要應用去及時的收包,將recv buffer的空間騰出,不然若流量繼續增加,最終還是會出現buffer滿而丟包的問題。

UDP收發包畢竟還是太簡單,只在IP層之上簡單提供收發包接口功能,不像TCP有擁塞控制和自動重傳機制,相比之下應用層就需要額外做對應的收發包控制工作,而使用TCP就省事簡單很多(當然實現高效的TCP通訊也不是簡單的事情)。

結尾吐槽一句:那些制定GB28181標准的磚家們,你們采用PS over RTP的封包格式時,是不是腦子進水了?要知道PS流只是適合媒體數據存儲的,而不是網絡傳輸啊,要進行網絡傳輸,干嘛不用TS封包?

~~ end ~~


免責聲明!

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



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