RTMP使用笔记(一):解析使用wireshark抓取的RTMP协议包_wireshark rtmp

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • DeMultiplexing(解复用):多路复用的逆过程,其中交织的音频和视频数据被组合以形成原始音频和视频数据。
  • Remote Procedure Call (RPC 远程方法调用):允许客户端或服务器在对等端调用子例程或过程的请求。
  • Metadata(元数据):有关数据的说明。 电影的元数据包括电影标题,持续时间,创建日期等。
  • Application Instance(应用实例):客户端通过发送连接请求连接的服务器上的应用程序实例。
  • Action Message Format (AMF 动作消息格式):一种紧凑的二进制格式,用于序列化ActionScript对象图。AMF有两个版本:AMF 0 [AMF0]和AMF 3 [AMF3]。

3. RTMP Chunk Stream

3.1. 消息格式

可以拆分为块以支持多路复用的消息格式取决于更高级别的协议。 但是,消息格式应该包含创建块所需的以下字段:

  • Timestamp:消息的时间戳。 该字段可以传输4个字节。
  • Length:消息有效负载的长度。 如果无法省略消息标题,则应将其包含在长度中。 该字段占用块头中的3个字节。
  • Type Id:类型ID的范围被保留用于协议控制消息。 这些传播信息的消息由RTMP Chunk Stream协议和更高级别的协议处理。 所有其他类型ID可供更高级别协议使用,并被RTMP Chunk Stream视为不透明值。 事实上,RTMP Chunk Stream中没有任何内容要求将这些值用作类型; 所有(非协议)消息可以是相同类型,或者应用程序可以使用此字段来区分同时跟踪而不是类型。 该字段在块头中占用1个字节。
  • Message Stream ID:消息流ID可以是任意值。 复用到同一块流上的不同消息流基于它们的消息流ID被多路分用。 除此之外,就RTMP Chunk Stream而言,这是一个不透明的值。该字段以小端格式占用块头中的4个字节。

3.2. 握手

RTMP连接以握手开始, 握手不同于协议的其余部分。它由三个静态大小的块组成,而不是由带有标题的可变大小的块组成。 客户端(已启动连接的端点)和服务器均发送相同的三个块。 对于展示,当客户端发送时,这些块将被指定为C0,C1和C2; S0,S1和S2由服务器发送。

3.2.1 握手顺序

  • 握手开始于客户端发送C0和C1块。
  • 在发送C2之前,客户端必须等待直到收到S1。
  • 在发送任何其他数据之前,客户端必须等待直到收到S2。
  • 在发送S0和S1之前,服务器必须等待直到收到C0,并且可以等到C1之后。 在发送S2之前,服务器必须等待直到收到C1。 在发送任何其他数据之前,服务器必须等待直到收到C2。

3.2.2 C0和S0格式

C0和S0数据包是单个八位字节,被视为单个8位整数字段:
在这里插入图片描述
以下是C0 / S0数据包中的字段:

版本(8位):在C0中,此字段标识客户端请求的RTMP版本。 在S0中,该字段标识服务器选择的RTMP版本。 此规范定义的版本为3。值0-2是早期专有产品使用的弃用值;4-31保留用于将来的实现;不允许使用32-255(允许区分RTMP与基于文本的协议,后者始终以可打印字符开头)。 无法识别客户端请求的版本的服务器应该响应3。客户端可以选择降级到版本3,或放弃握手。

3.2.2 C1和S1格式

C1和S1数据包长度为1536个八位字节,由以下字段组成:
在这里插入图片描述

  • Time (4 bytes):该字段包含一个时间戳,该时间戳应该用作从该端点发送的所有未来块的时间起点。 这可以是0,或某个任意值。 为了同步多个块流,端点可能希望发送另一个块流的时间戳的当前值。
  • Zero (4 bytes):该字段必须全为0。
  • Random data (1528 bytes):该字段可以包含任意值。 由于每个端点必须区分对其已启动的握手的响应和由其对等方发起的握手,因此该数据应该发送足够随机的内容。 但是不需要加密安全随机性,甚至动态值。

3.2.3 C2和S2格式

C2和S2数据包长1536个八位字节,几乎是S1和C1(分别)的回声,由以下字段组成:
在这里插入图片描述

  • Time (4 bytes):该字段必须包含对等体在S1(对于C2)或C1(对于S2)中发送的时间戳。
  • Time2 (4 bytes):该字段必须包含读取对等体发送的先前分组(s1或c1)的时间戳。
  • Random echo (1528 bytes):该字段必须包含对等体在S1(对于C2)或S2(对于C1)中发送的随机数据字段。 对等体可以将时间和时间2字段与当前时间戳一起用作连接的带宽和/或延迟的快速估计,但这不太可能有用。

3.2.4 握手图
在这里插入图片描述下面介绍握手图中提到的状态:

  • Uninitialized(未初始化的):协议版本在此阶段发送。 客户端和服务器都未初始化。 客户端在数据包C0中发送协议版本。 如果服务器支持该版本,它将发送S0和S1作为响应。 如果不是,则服务器通过采取适当的操作进行响应。 在RTMP中,此操作正在终止连接。
  • Version Sent(版本已发送):在未初始化状态之后,客户端和服务器都处于“已发送”状态。 客户端正在等待数据包S1,服务器正在等待数据包C1。 在接收到等待的分组时,客户端发送分组C2,并且服务器发送分组S2。 然后该状态成为Ack Sent。
  • Ack Sent(确认已发送):客户端和服务器分别等待S2和C2。
  • Handshake Done(握手完成):客户端和服务器交换消息。

3.4 分块

在握手之后,连接多路复用一个或多个块流。 每个块流携带来自一个消息流的一种类型的消息。 创建的每个块都有一个与之关联的唯一ID,称为chunk stream ID。 块通过网络传输。 在传输时,每个块必须在下一个块之前完全发送。 在接收器端,基于块流ID将块组装成消息。

分块允许将较高级别协议中的大型消息分解为较小的消息,例如,以防止较大的低优先级消息(例如视频)阻塞较小的高优先级消息(例如音频或控制)。

分块还允许以较少的开销发送小消息,因为块头包含信息的压缩表示,否则必须将其包括在消息本身中。

块大小是可配置的。 可以使用Set Chunk Size控制消息设置它。更大的块大小可以降低 CPU 开销,但在低带宽连接时因为它的大量的写入也会延迟其他内容的传递。更小的块不利于高比特率的流化。所以块的大小设置取决于具体情况。

3.4.1 块格式

每个块包含标题和数据,标题本身有三个部分:
在这里插入图片描述

  • Basic Header(基本头,1 到 3 个字节):该字段对块流ID和块类型进行编码。 块类型确定编码消息头的格式。长度完全取决于块流ID,块ID是可变长度字段。
  • Message Header(消息头,0,3,7,或者 11 个字节):该字段对有关正在发送的消息(无论是全部还是部分)的信息进行编码。 可以使用块头中指定的块类型来确定长度。

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

s/618679757)**

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值