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单元标记结束一个视频帧的结束。
    在这里插入图片描述

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