RTMP(1):Handshake

前言

最近学习了 RTMP,自己也简单实现了一个 RTMP 服务器,可以和 FFmpeg 交互实现推拉流。接下来计划写几篇笔记梳理一下,欢迎大家斧正~

本系列的内容主要来自 Adobe 的 《RTMP specification 1.0》,我看的这版发表于 2012.12.21,距今已经快十年啦~

我把该文档上传到网盘了,大家自取~

链接: https://pan.baidu.com/s/1nZzYPWB2sl5at-lTiYwxMA
提取码: fqan

协议特点

Real Time Messaging Protocol 有以下几个特点:

  • 支持双向传输。
  • 一条连接支持传输不同用途的消息,比如 (有啥用后面再讲)
    • Protocol Control Message
    • RTMP Message
    • RTMP Command Message
  • 借助 chunk 的概念,在一个链接上可以“同时”传输多个消息。
  • 依赖可靠的传输层协议,比如TCP。

握手过程

类似 TCP,RTMP 在发送数据之前也有一个握手过程。整个过程如下图所示:
RTMP握手过程
RTMP 的握手过程有什么用呢?大家也可以带着这个问题读下去,后面我罗列了一些网上的答案,还有自己的一点思考。

报文格式

C0 和 S0

C0 和 S0 的格式一致,仅一个字节,用于表示自身支持的协议版本,目前一般是 3。

C1 和 S1

C1 和 S1 的格式一致,如下图示,共包含四个字段。

time (4 bytes)

时间戳,可以是任意值。FFmpeg 的实现将该值设为 0。

zero (4 bytes)

协议中规定该字段必须是零值。但我在于 FFmpeg 交互时,发现该值被设为 151026690
在这里插入图片描述
看了下 libavformat/rtmpproto.c 中实现,发现 FFmpeg 将 Flash 的版本号填充至该字段了。工业界潜规则?

/**
 * emulated Flash client version - 9.0.124.2 on Linux
 * @{
 */
#define RTMP_CLIENT_PLATFORM "LNX"
#define RTMP_CLIENT_VER1    9
#define RTMP_CLIENT_VER2    0
#define RTMP_CLIENT_VER3  124
#define RTMP_CLIENT_VER4    2
/** @} */ //version defines

static int rtmp_handshake(URLContext *s, RTMPContext *rt)
{
    AVLFG rnd;
    uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
        3,                // unencrypted data
        0, 0, 0, 0,       // client uptime
        RTMP_CLIENT_VER1,
        RTMP_CLIENT_VER2,
        RTMP_CLIENT_VER3,
        RTMP_CLIENT_VER4,
    };
...

random bytes (1528 bytes)

random bytes 部分长 1528 字节,其值可以是任意值。

C2 和 S2

C2 和 S2 格式是一致的,如下图所示:

time (4 bytes)

对端发来的包中的时间戳,即

  • C2.time = S1.time
  • S2.time = C1.time

time2 (4 bytes)

发给对端的前一个包中的时间戳,即

  • C2.time2 = C1.time
  • S2.time2 = S1.time

random echo (1528 bytes)

值如其名。将对端发来的 random bytes 返回去,即

  • C2.random_echo = S1.random_bytes
  • S2.random_echo = C1.random_bytes

为啥要握手

在发送完 C2/S2 后,client 和 server 分别进入 Handshake Done 状态,就可以开始传输数据了。那么握手有何作用呢?总结了两点:

  • 协商 client 和 server 所使用的的协议版本。
  • 通过 C2/S2 中的时间戳,接收端可以粗略的估计时延和带宽,但好像没啥用。文档原文是:

Either peer can use the time and time2 fields together with the current timestamp as a quick estimate of the bandwidth and/or latency of the connection, but this is unlikely to be useful.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值