前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手撕Rtmp协议细节(6)——connect后续三剑客

手撕Rtmp协议细节(6)——connect后续三剑客

作者头像
视界音你而不同
发布2020-05-20 00:40:12
2K1
发布2020-05-20 00:40:12
举报

在讲解connect消息的时候,我们说过服务器收到connect消息之后,会向客户端发送Window Acknowledgement Size消息和Set Peer Bandwidth消息,这一篇就来介绍一下这两条消息。

1.概览

首先从抓包文件看一下:

示例中服务器ip地址是192.17.1.200,客户端ip地址是192.17.1.92,客户端向服务器发送connect消息之后,服务器向客户端发送了Window Acknowledgement Size和Set Peer Bandwidth消息。

2.Window Acknowledgement Size消息

Window Acknowledgement Size用来通知对端,如果收到该大小字节的数据,需要回复一个Acknowledgement消息,也就是ACK。本例中,设置的大小为500000,也就是服务端通知客户端如果收到了50000字节的数据,需要向服务端发送一个ACK的消息,而实际上一般情况一个会话中能达到如此大的数据量比较少,所以我们也看到会回复ACK消息的消息比较少,更多的只是看到设置接收窗口大小的消息(Window Acknowledgement Size),接下来我们看一下抓包。

消息格式比较简单,组织结构是RTMP Header + RTMP Body,Header的结构就不赘述了,参考前面的文章;Body中直接使用4个字节表示要设置的大小,此处为0x004c4b40=5000000。

3.Acknowlegement消息

Acknowlegement消息可以理解为Window Acknowlegement Size满足条件的触发消息,当一端收到的数据大小满足Window Acknowledgement Size设置的大小时,向对端发送Ack消息。

Acknowlegement消息,也按照RTMP Header + RTMP Body进行组织,其Body也直接使用4个字节,表示收到数据满足Window Acknowledgement Size的最后一个数据包的序列号。我们来看一个抓包文件:

该条消息表示,在序列号为2507670的时候,rtmp客户端已累计收到5000000个字节的数据,此时向服务端发送一个ACK。

另外我们也验证一下,交互过程中,更多的看到Window Acknowledgement Size消息,而很少看到Acknowlegement消息。

说明:wireshark中可以针对rtmp消息进行过滤

过滤Window Acknowledgement Size

rtmpt.header.typeid == 0x05

过滤Acknowledgement

rtmpt.header.typeid == 0x03

照猫画虎,可以对照下表进行过滤:

typeID

消息类型

说明

0x00

Unkown

0x01

Set Chunk Size

设置Chunk大小

0x02

Abort

0x03

Window Acknowledgement Size

0x04

User Control Message

空户控制消息(如Stream Begin等)

0x05

Acknowledgement

0x06

Set Peer Bandwidth

更多的关于wireshark抓包关于rtmp的过滤条件,参照:

代码语言:javascript
复制
https://www.wireshark.org/docs/dfref/r/rtmpt.html

4.Set Peer BandWidth消息

该消息里设置对端输出带宽,对端是通过设置Window Acknowledgement Size来实现流量控制的。超过Window Acknowledgement Size后未确认(不发送Acknowledgement)发送端将不再发送消息。所以对端收到set peer bandwidth后,如果之前发送的Window Acknowledgement Size和这里写的的Window Acknowledgement Size不一样,一般会发送一个Window Acknowledgement Size。

刚开始建立连接,服务器向客户端发送Set Peer Bandwidth消息,客户端第一次收到Set Peer Bandwidth消息,之前没有发送过Window Acknowledgement Size,所以在这里向服务端发送一次消息。

还是看抓包文件:

Set Peer Bandwidth消息还是按照RTMP Header + RTMP Body的格式组成。RTMP Body由两个字段组成,一个是Window acknowledgement size,占用4个字节;一个是limit type,表示限制的类型,可取的值为0(Hard),1(soft), 2(Dynamic)。本例中采用的是Dynamic。

  • limity type表示了不同的限制策略:
  • Hard:收到消息的一端需要按照消息中设置的Window size进行限制;
  • Soft:收到消息的一端按照消息中设置的Window size或者已经生效的限制进行限制,以两者中较小的为准。
  • Dynamic:如果之前的类型为Hard,则此消息也为Hard类型,否则忽略该类型。

5.StreamBegin

服务端发送Set Peer Bandwidth消息之后,客户端向服务端发送Window Acknowledgement Size消息,服务端再向客户端发送一条用户控制消息StreamBegin。

wireshark中过滤StreamBegin消息的条件如下:

代码语言:javascript
复制
rtmpt.header.typeid == 0x04 and rtmpt.ucm.eventtype == 0x00

StreamBegin属于用户控制类消息,header的typeid为0x04。而用户控制消息的类型的定义如下:

type

消息

说明

0x00

Stream Begin

0x01

Stream EOF

0x02

Stream Dry

0x03

SetBufferLength

0x04

StreamIsRecoreded

0x06

PingRequest

0x07

PringResponse

如此,我们就得出了StreamBegin的过滤条件。接下来我们看看StreamBegin消息,还是先看一下抓包文件:

RTMP服务器发送StreamBegin以通知客户端流已经可以使用并且可以用于通信。默认情况下,从客户端成功接收到connect命令后,将在ID 0上发送StreamBegin。StreamBegin的数据字段占用4字节,其类型占用2个字节,所以RTMP Body部分总共占用6个字节(类型+数据)。其中数据字段代表已开始运行的流的流ID,此例中为1。

好了,这一篇就到这里了,下一篇我们继续手撕Rtmp协议细节,不要走远!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 视界音你而不同 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档