一、UDP的特性與應用場景
采用UDP有3個關鍵點:
- 網(wǎng)絡帶寬需求較小,而實時性要求高
- 大部分應用無需維持連接
- 需要低功耗
應用場景:
- 網(wǎng)頁瀏覽:新浪微博就已經(jīng)用了QUIC協(xié)議
- 流媒體:WebRTC就是基于UDP的
- 實時游戲:Unity3D采用的RakNet也是基于UDP的協(xié)議
基于UDP協(xié)議的QUIC協(xié)議
QUIC(Quick UDP Internet Connection)是谷歌制定的一種基于UDP的低時延的互聯(lián)網(wǎng)傳輸層協(xié)議
詳情可參閱:
https://eng.uber.com/employing-quic-protocol/
UDP傳輸時需要注意的問題
- 數(shù)據(jù)包確認機制
- 數(shù)據(jù)包重傳機制
- 盡量不發(fā)送大于路徑MTU的數(shù)據(jù)包
- 處理數(shù)據(jù)包重排
二、UDP與MTU
IP分片的概念
- 在TCP/IP分層中,數(shù)據(jù)鏈路層用MTU(Maximum Transmission Unit,最大傳輸單元)來限制所能傳輸?shù)臄?shù)據(jù)包大小,MTU是指一次傳送的數(shù)據(jù)最大長度,不包括數(shù)據(jù)鏈路層數(shù)據(jù)幀的幀頭,如以太網(wǎng)的MTU為1500字節(jié),實際上數(shù)據(jù)幀的最大長度為1514字節(jié),其中以太網(wǎng)數(shù)據(jù)幀的幀頭為14字節(jié)
- 當發(fā)送的IP數(shù)據(jù)包的大小超過了MTU時,IP層就需要對數(shù)據(jù)進行分片,否則數(shù)據(jù)將無法發(fā)送成功
- IP層是沒有超時重傳機制的,如果IP層對一個數(shù)據(jù)包進行了分片,只要有一個分片丟失了,只能依賴于傳輸層進行重傳,結(jié)果是所有的分片都要重傳一遍,這個代價有點大;公網(wǎng)傳輸,需要經(jīng)過多個網(wǎng)絡設備,IP分片容易造成丟包
- 由此可見,IP分片會大大降低傳輸層傳送數(shù)據(jù)的成功率,所以我們要避免IP分片
UDP與MTU的關系
MTU是指通信協(xié)議的鏈路層上面所能通過的最大數(shù)據(jù)包大小
單個UDP傳輸?shù)淖畲髢?nèi)容1472字節(jié),但由于不同的網(wǎng)絡中轉(zhuǎn)設備設置的MTU值并不相同:
- Internet環(huán)境下:標準MTU值為576字節(jié),UDP的數(shù)據(jù)長度應該控制在548字節(jié)(576-8-20)以內(nèi)
- 局域網(wǎng)環(huán)境下:UDP的數(shù)據(jù)長度控制在1472個字節(jié)以內(nèi)
三、UDP分包與組包設計
為什么要對UDP進行分包與組包
- 通過上面對MTU的介紹我們知道,如果IP數(shù)據(jù)包的大小超過了其所在環(huán)境中MTU的大小,那么就會對IP數(shù)據(jù)包進行分片
- 當分片只要其中一個片段丟失,那么就需要重傳所有的分片數(shù)據(jù),因此這種消耗是比較大的
主要思想
- 在應用層,我們對UDP數(shù)據(jù)進行傳輸時調(diào)用的兩個接口為sendto()和recvfrom()
- 我們將傳輸?shù)臄?shù)據(jù)(原始數(shù)據(jù),可能很大)分割為一個一個小的分片,使分片的大小不大于MTU的大小,這樣我們在進行UDP數(shù)據(jù)傳輸?shù)臅r候,就不會產(chǎn)生上面IP分片的問題了
對于每一個分片我們需要設計其格式,例如下面是定義的一種格式。相關字段為如下所示
代碼
GIthub鏈接:
https://github.com/dongyusheng/csdn-code/tree/master/udp_piece
其中:
circular_buffer.h/.c:環(huán)形緩沖區(qū),用來保存數(shù)據(jù)的
udp-piece.h/.c:UDP分片與重組(核心代碼)
udp-piece-client.c:客戶端測試代碼,代碼內(nèi)會向服務端發(fā)送UDP數(shù)據(jù)
udp-piece-server.c:服務端測試代碼,接收客戶端的UDP數(shù)據(jù)
編碼主要思路
udp-piece.h:
定義了如下的宏和結(jié)構(gòu),主要用來描述分片節(jié)點的
其中比較重要的一個字段為PIECE_FIX_SIZE,其代表我們分片中實際數(shù)據(jù)的長度,因為Internet中MTU的大小通常為576,所以我們的UDP數(shù)據(jù)包最好不要超過576-8-20大?。?為UDP頭大小,20位IP報文大?。硗膺€要減去12(因為我們分片也有頭,為12字節(jié))
udp-piece-client.c: 其向服務端發(fā)送一長串字符串,在發(fā)送之前先調(diào)用udp_piece_cut()對整個UDP數(shù)據(jù)包進行分片,然后逐個發(fā)送出去
udp-piece-server.c: 其從客戶端接收UDP數(shù)據(jù),將接收的數(shù)據(jù)放到環(huán)形緩沖中,然后進行重組
小結(jié)
本文只介紹了“UDP的分包與組包”,并沒有涉及到UDP數(shù)據(jù)包確認、重傳等機制,并且代碼也只做到了分包與組包。
-
互聯(lián)網(wǎng)
+關注
關注
54文章
11013瀏覽量
102081 -
UDP
+關注
關注
0文章
317瀏覽量
33801 -
數(shù)據(jù)鏈
+關注
關注
2文章
37瀏覽量
15736 -
網(wǎng)絡帶寬
+關注
關注
0文章
34瀏覽量
8161
發(fā)布評論請先 登錄
相關推薦
評論