mac、ip、tcp/udp、rtmp/rtp...

1、基本知識

https://blog.csdn.net/zpoison/article/details/86528327
元數據進行網絡傳輸,需要先進行逐層封裝和逐層解析的過程,如下圖:
在這裏插入圖片描述
協議與上下層關係簡圖
在這裏插入圖片描述

1.1 以太網幀 MAC幀

MAC幀是數據幀的一種,數據鏈路層的協議數據單元,包括三部分,幀頭幀尾包含一些必要的控制信息,比如同步信息、地址信息、差錯控制信息等;數據部分則包含網絡層傳下來的數據,比如ip數據包。
在這裏插入圖片描述

MAC層要求定界字符之後的內容要在64字節到1518個字節之間,其中包括14字節的幀頭(目標MAC和源MAC,數據長度),4字節的幀尾(FCS,校驗值),46-1500數據部分(這裏是IP報文數據,IP報文數據通常最大爲MTU值1500,最小爲僅IP包頭40字節)。
通常我們用whireshark抓包TCP時,只會看到mac幀頭和數據部分,也就是一個包的數據長度爲14+(20+20 ~ 1500),即54 ~ 1514長度。(UDP爲14+(20+8 ~ 1500)即42~1514長度)
在這裏插入圖片描述

1.2 IP包

ip地址長度爲32bit,普通的IP包頭長爲20個字節(若有選項數據再增加m大小選項數據)。IP包的數據部分,通常是TCP數據包/UDP數據包。
在這裏插入圖片描述
IP包數據長度爲20(+m) + N,由於MTU=1500,所以IP數據長度至多爲1480字節。

1.3 UDP包

用戶數據報協議UDP(User Datagram Protocol),是無連接的,盡最大可能交付,沒有擁塞控制,面向報文(對於應用程序傳下來的報文不合並也不拆分,只是添加UDP首部)。
在這裏插入圖片描述
UDP首部佔用8個字節。當IP數據包首部爲20字節,所有UDP數據包爲下圖。
在這裏插入圖片描述
此時,UDP的數據長度至多爲(1500-20)-8 = 1480 - 8 = 1472字節。
抓包示意如下,顯示的Length是網絡包長度,1500+14, Len是UDP數據長度。
在這裏插入圖片描述

1.4 TCP包

TCP提供一種面向連接的、可靠的字節流服務。 所以TCP要比UDP可靠的多,UDP是把數據直接發出去,而不管對方是不是在收信。
在這裏插入圖片描述
TCP首部佔用20個字節。當IP數據包首部爲20字節,所有TCP數據包爲下圖。
在這裏插入圖片描述
此時,TCP的數據長度至多爲(1500-20)-20 = 1480 - 20 = 1460字節。

1.5 RTP/RTCP包

1.5.1 RTP包頭

在這裏插入圖片描述

  1. V:RTP協議的版本號,佔2位,當前協議版本號爲2
  2. P:填充標誌,佔1位,如果P=1,則在該報文的尾部填充一個或多個額外的八位組,它們不是有效載荷的一部分。
  3. X:擴展標誌,佔1位,如果X=1,則在RTP報頭後跟有一個擴展報頭
  4. CC:CSRC計數器,佔4位,指示CSRC 標識符的個數
  5. M: 標記,佔1位,不同的有效載荷有不同的含義,對於視頻,標記一幀的結束;對於音頻,標記會話的開始。
  6. PT: 有效荷載類型,佔7位,用於說明RTP報文中有效載荷的類型,如GSM音頻、JPEM圖像等,在流媒體中大部分是用來區分音頻流和視頻流的,這樣便於客戶端進行解析。
  7. 序列號:佔16位,用於標識發送者所發送的RTP報文的序列號,每發送一個報文,序列號增1。這個字段當下層的承載協議用UDP的時候,網絡狀況不好的時候可以用來檢查丟包。同時出現網絡抖動的情況可以用來對數據進行重新排序,序列號的初始值是隨機的,同時音頻包和視頻包的sequence是分別記數的。
  8. 時戳(Timestamp):佔32位,必須使用90 kHz 時鐘頻率。時戳反映了該RTP報文的第一個八位組的採樣時刻。接收者使用時戳來計算延遲和延遲抖動,並進行同步控制。
  9. 同步信源(SSRC)標識符:佔32位,用於標識同步信源。該標識符是隨機選擇的,參加同一視頻會議的兩個同步信源不能有相同的SSRC。
  10. 特約信源(CSRC)標識符:每個CSRC標識符佔32位,可以有0~15個。每個CSRC標識了包含在該RTP報文有效載荷中的所有特約信源。

注:基本的RTP說明並不定義任何頭擴展本身,如果遇到X=1,需要特殊處理,擴展數據在CSRC(若有)後、負載前,格式如下:
在這裏插入圖片描述
以上,rtp包的包頭當CC位爲0時,表示無CSRC,那麼RTP包頭長12個字節。因此 :
1)當rtp走tcp時,rtp載荷長度最多爲 1460 – 12 = 1448個字節。
2)當rtp走udp時,rtp載荷長度最多爲 1472 – 12 = 1460個字節。

1.5.2 RTP封包

載荷第一個字節(或NALU單元) 格式定義如下,包含禁止位F、重要級別NRI、類型Type。
在這裏插入圖片描述在這裏插入圖片描述
常用的NALU Header對應的type數值:
在這裏插入圖片描述
由於i幀比較大,已經超出mtu最大1500,所以需要拆包分片傳輸,這裏說的拆包發送不是指發送超過1500的數據包時tcp的分段傳輸或者upd的ip分片傳輸,而是指rtp協議本身對264的拆包。(rtmp打包就比較簡單,由於是基於tcp的協議,大包直接交給tcp去做分段傳輸,rtmp通過設置合適的trunk size去發送一幀幀數據。)

如果小於MTU採用單個NAL單元包,如果大於MTU就採用FUs分片方式。常用的打包方式就是單個NAL包和FU-A方式,所以我們只解析這兩種。

1.5.2.1 單個NALU單元包

P幀或者B幀比較小的包,直接將NALU打包成RTP包進行傳輸。
RTP header(12bytes) + NALU header (1byte) + NALU payload
在這裏插入圖片描述

1.5.2.2 分片單元FU-A

相同NAL單元的分片必須使用遞增的RTP序號連續順序發送(第一和最後分片之間沒有其他的RTP包)。相似,NAL單元必須按照RTP順序號的順序裝配。
RTP header(12bytes) + FU Indicator(1byte) + FU header(1 byte) + FU payload
在這裏插入圖片描述
FU-A由1字節的分片單元指示(如下圖左),1字節的分片單元頭(如下圖右),
在這裏插入圖片描述 在這裏插入圖片描述

其中分片單元頭各字結位如下:

  1. S: 1 bit 當設置成1,開始位指示分片NAL單元的開始。
    當跟隨的FU荷載不是分片NALU單元荷載的開始,開始位設爲0。
  2. E: 1 bit 當設置成1, 結束位指示分片NAL單元的結束,即荷載的最後字節也是分片NALU單元的最後一個字節。
    當跟隨的FU荷載不是分片NAL單元的最後分片,結束位設置爲0。
  3. R: 1 bit 保留位必須設置爲0,接收者必須忽略該位

分片開始 SE = 10, 分片中間 SE = 00, 分片結束 SE = 01

這裏分片傳輸方式是無NALU頭,實際上是NALU頭被分散填充到FU indicator和FU header裏面了。bit位按照從左到右編號0-7來算,nalu頭中0-2前三個bit放在FU indicator的0-2前三個bit中,後3-7五個bit放入FU header的後3-7五個中。

反過來,NALU Header 由FU indicator前三位和FU header後五位組成,即:
NALU header = (FU indicator & 0xe0) | (FU header & 0x1F)

1.5.2.3 抓包演示

—>RTP包中接收的264包是不含有0x00,0x00,0x00,0x01頭的,這部分是rtp接收以後,另外再加上去的,解碼的時候再做判斷的。(whireshark不能解析rtp時,右邊解碼爲RTP)。

  1. SPS、PPS
    RTP數據部分第一個字節0x18,後五位11000, 24, STAP-A單一時間聚合包。
    在這裏插入圖片描述
    在這裏插入圖片描述
    第一個包長度0x0002,數據0x0910, nalu header 0x09,不重要,分隔符
    第二個包長度0x001b,nalu header 0x27,F=0, NRI=2, TYPE= SPS
    第二個包長度0x0004,nalu header 0x28,F=0, NRI=2, TYPE= PPS

  2. I幀分片開始
    RTP數據部分第一個字節0x3C,後五位11100, 28, FU-A分片
    第二個字節分片頭0x85, S=1, E=0, 分片開始, 後五位是00101,5, I幀
    在這裏插入圖片描述

  3. I幀分片
    分片指示單元 0x3c 後五位11100, 28, FU-A分片
    分片單元頭 0x05 S=0, E=0, 分片,後五位是00101,5, I幀
    同一個I幀的分片,時間戳相同。
    在這裏插入圖片描述

  4. I幀結束
    這裏比較特殊,沒有使用分片單元描述結束。
    使用的是NALU單元標記結束一個視頻幀的結束。
    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章