介绍
我这个系列讲解音视频相关的协议,这部分内容比较多,我打算分成好几篇讲,感兴趣的读者可以关注一下。有了以上的基础,我就打算做一个音视频的网络服务器。如果您觉得读起来有点困难,可以先补一下计算机网络的知识,主要是TCP,UDP,HTTP相关的知识。
讲解
RTMP (Real-Time Messaging Protocol)握手时消息交互的重要部分,RTMP 的连接就是从握手开始的。今天这篇文章深入解析 RTMP 的握手过程。
客户端和服务端各自发送三个块,客户端的为 C0,C1,C2,服务端发送的为 S0,S1,S2。
握手顺序
RTMP 协议本身并没有规定这 6 个消息的具体传输顺序,但 RTMP 协议的实现者需要保证这几点:
-
客户端发送 C0 和 C1 块开始握手。
-
客户端必须等接收到 S1 后才能发送 C2。
-
客户端必须等接收到 S2 后才能发送其它数据。
-
服务器必须等接收到 C0 才能发送 S0 和 S1,也可以(MAY)等接到 C1 一起之后。
-
服务器必须等到 C1 才能发送 S2。
-
服务器必须等到 C2 才能发送其它数据。
C0、S0 格式
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
| version |
+-+-+-+-+-+-+-+-+
C0 and S0 bits
在 C0 中,该字段标识了客户端请求的 RTMP 版本。
在 S0 中,这个字段是服务器的 RTMP 版本。
C1、S1 格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| zero (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random bytes |
| (cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
C1 and S1 bits
time:包含一个时间戳
zero:该字段必须是全零
random bytes:随机数
C2、S2 格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time2 (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random echo |
| (cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
C2 and S2 bits
time:包含对端发送的时间戳
time2:包含前一个对端发送并且已被读取的时间戳
握手流程图:
+-------------+ +-------------+
| Client | TCP/IP Network | Server |
+-------------+ | +-------------+
| | |
Uninitialized | Uninitialized
| C0 | |
|------------------->| C0 |
| |-------------------->|
| C1 | |
|------------------->| S0 |
| |<--------------------|
| | S1 |
Version sent |<--------------------|
| S0 | |
|<-------------------| |
| S1 | |
|<-------------------| Version sent
| | C1 |
| |-------------------->|
| C2 | |
|------------------->| S2 |
| |<--------------------|
Ack sent | Ack Sent
| S2 | |
|<-------------------| |
| | C2 |
| |-------------------->|
Handshake Done | Handshake Done
| | |
Pictorial Representation of Handshake
这个图看起来比较复杂,我用文字为大家解释,这样更好理解一点
-
未初始化(Uninitialized):协议的版本发送出去的这个阶段。客户端与服务器都是未初始化态。客户端在 C0 中发送协议版本。如果服务器支持这个版本,它将回应 S0 和 S1。如果不支持,服务器将会采取适当措施的回应。在 RTMP 中,这个措施是终止连接。
-
版本已发送(Version Sent):客户端和服务器在未初始化态后是版本已发送态。客户端等待 S1,服务器在等待 C1。在接收到响应包后,客户端发送 C2,服务器发送 S2。状态就变成了确认已发送。
-
确认已发送(Ack Send):客户端和服务器分别在等 S2 和 C2。
-
握手完成(Handshake Done):客户端与服务器可以交换消息了。
好了,总结一下,今天大致讲解了 RTMP 的握手顺序,RTMP 的客户端,服务端发送的包格式,还有握手流程。
欲知后事如何,请听下回分解。