janus123hjg

RTMP协议(二)握手流程

2020-07-03  本文已影响0人  Seacen_Liu

若要建立一个有效的 RTMPConnection链接,首先需要“握手”:客户端要向服务器按序发送C0,C1,C2三个chunk,服务器向客户端按序发送S0,S1,S2三个chunk,然后才能进行有效的信息传输。RTMP 协议本身并没有规定这6个信息的具体传输顺序,但 RTMP 协议的实现者需要保证这几点如下:

握手示意图

+-------------+                           +-------------+
|    Client   |       TCP/IP Network      |    Server   |
+-------------+            |              +-------------+
      |                    |                     |
Uninitialized              |               Uninitialized
      |          C0        |                     |
      |------------------->|         C0          |
      |                    |-------------------->|
      |          C1        |                     |
      |------------------->|         S0          |
      |                    |<--------------------|
      |                    |         S1          |
 Version Sent              |<--------------------|
      |          S0        |                     |
      |<-------------------|                     |
      |          S1        |                     |
      |<-------------------|                Version Sent
      |                    |         C1          |
      |                    |-------------------->|
      |          C2        |                     |
      |------------------->|         S2          |
      |                    |<--------------------|
   AckSSent                |                  Ack Sent
      |          S2        |                     |
      |<-------------------|                     |
      |                    |         C2          |
      |                    |-------------------->|
 Handshake Done            |               Handshake Done
      |                    |                     |
          Pictorial Representation Of Handshake

握手状态

握手数据格式

在 Flash10.1 之后,Adobe 对 RTMP 握手进行了一轮修改,握手的步骤和上文记述的没有不同,而是对握手的数据进行了修改,采用了加密数据。因此,现在存在两种握手数据,一般通过C1[4:8]是否为0来区分。我们将使用0值称为简单握手(simple handshake),将非0值的称为复杂握手(complex handshake)。

简单握手 - simple handshake

C0 和 S0(1 byte)

    +-+-+-+-+-+-+-+-+-+-+-+
    |  version (1 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+-+

C1 和 S1(1536 bytes)

    +-+-+-+-+-+-+-+-+-+-+
    |   time (4 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+
    |   zero (4 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+
    |   random bytes    |
    +-+-+-+-+-+-+-+-+-+-+
    |   random bytes    |
    |      (cont)       |
    |       ....        |
    +-+-+-+-+-+-+-+-+-+-+

C2 和 S2(1536 bytes)

    +-+-+-+-+-+-+-+-+-+-+
    |   time (4 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+
    |  time2 (4 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+
    |   random bytes    |
    +-+-+-+-+-+-+-+-+-+-+
    |   random bytes    |
    |      (cont)       |
    |       ....        |
    +-+-+-+-+-+-+-+-+-+-+

握手的双方可以使用``timetime2` 字段来估算网络连接的带宽和或延迟,但是不一定有用。

复杂握手 - complex handshake

C0 和 S0(1 byte)

    +-+-+-+-+-+-+-+-+-+-+-+
    |  version (1 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+-+

C1 和 S1(1536 bytes)

    +-+-+-+-+-+-+-+-+-+-+
    |   time (4 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+
    | version (4 bytes) |
    +-+-+-+-+-+-+-+-+-+-+
    |   key (764 bytes) |
    +-+-+-+-+-+-+-+-+-+-+
    | digest (764 bytes)|
    +-+-+-+-+-+-+-+-+-+-+

在不同的包里,keydiest顺序可能会颠倒,比如nginx-rtmp

C2 和 S2(1536 bytes)

    +-+-+-+-+-+-+-+-+-+-+-+-+-+
    | random-data (1504 bytes)|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+
    | digest-data (32 bytes)  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+

digest的计算方式较为复杂,后续再补全

握手流程设计的理解

实现选用的流程

为了方便开发,在实现上,我们选用以下握手流程,这样服务端可以连续发送S0,S1S2

  1. Client--> Server : 发送一个创建流的请求(C0C1)
  2. Server--> Client : 返回一个流的索引号( S0S1S2)。
  3. Client--> Server : 开始发送 (C2)
  4. Client--> Server : 发送音视频数据(这些包用流的索引号来唯一标识)
上一篇下一篇

猜你喜欢

热点阅读