- RTMP協議是Real Time Message Protocol(實時信息傳輸協議)的縮寫,它是由Adobe公司提出的一種應用層的協議。
- RTMP協議基於TCP協議,依靠TCP協議提供可靠的數據傳輸,因此數據在網絡上傳輸不會出現丟包的情況。
- RTMP協議連接可靠,多路複用,延時容易受到網絡狀態的影響。
引用一段很多地方都能看到的話,
握手、消息塊概念
握手的目的是爲了確認對端RTMP的Version和確認對端能互相通信。
消息塊就是消息的載體,是RTMP協議最重要的載體,這個載體是有一定格式的,如果把Client和Server端當作鐵路的兩個站點,那這個消息塊就是火車,它負責運輸貨物。正如火車有火車頭、車廂一樣,消息塊也有基本頭,消息頭和消息負載。
RTMP協議當中,除了握手協議,其他的數據都是以消息塊的方式發送的,發送一個消息時,當塊大小比需要發送的消息的字節數更大時,一個消息塊就相當於一個消息,否則消息需要分成多個消息塊。
握手
RTMP的握手分爲簡單握手和複雜握手。
簡單握手
要建立一個可靠的RTMP connection,首先需要Client和Server兩者通過協議進行握手操作。基本的簡單握手流程有以下幾個流程:
+-+-+-+-+-+-+ +-+-+-+-+-+-+
| Client | | Server |
+-+-+-+-+-+-+ +-+-+-+-+-+-+
|-------- C0 C1 -------->|
|<------ S0 S1 S2 -------|
|--------- C2 ---------->|
握手是一切的開始,Client和Server兩個站點之前要運輸貨物,首先得先互相通知對方,確認鐵軌是否符合火車運行,是否暢通無阻,是否能準確的運輸貨物到對端。
客戶端要向服務器發送C0,C1,C2(按序)三個chunk,服務器向客戶端發送S0,S1,S2(按序)三個chunk,然後才能進行有效的信息傳輸。RTMP協議本身並沒有規定這6個Message的具體傳輸順序,但RTMP協議的實現者需要保證這幾點如下:
- 客戶端要等收到S1之後才能發送C2
- 客戶端要等收到S2之後才能發送其他信息(控制信息和真實音視頻等數據)
- 服務端要等到收到C0之後發送S1
- 服務端必須等到收到C1之後才能發送S2
- 服務端必須等到收到C2之後才能發送其他信息(控制信息和真實音視頻等數據)
實際的流程大概是這樣的:
- Client發送帶有1byte的C0和固定長度爲1536byte的C1;
- Server發送S0S1S2給Client;
- Client發送C2。
C0和S0的格式
+-+-+-+-+-+-+-+-+
| version |
+-+-+-+-+-+-+-+-+
1字節,Client端和Server端使用的RTMP版本。
C1和S1的格式
+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+
| zero (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+
| random bytes |
+-+-+-+-+-+-+-+-+-+-+
|random bytes(cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+
共1536個字節。
- time: 4 字節
本字段包含時間戳。該時間戳應該是發送這個數據塊的端點的後續塊的時間起始點。
可以是 0 ,或其他的任何值。爲了同步多個流,端點可能發送其塊流的當前值。 - zero: 4 字節
本字段必須是全零。 - random bytes: 1528 字節。
本字段可以包含任何值。終端需要區分出響應來自它發起的握手還是對端發起的握手,這個數據應該發送一些足夠隨機的數。這個不需要對隨機數進行加密保護,也不需要動態值。
C2和S2的格式
+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+
| time2(4 bytes) |
+-+-+-+-+-+-+-+-+-+-+
| random bytes |
+-+-+-+-+-+-+-+-+-+-+
|random bytes(cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+
- time: 4 字節
本字段必須包含對等段發送的時間,即:如果當前是C2,需要截取S1發過來的時間戳; 如果當前是S2,需要截取C1發過來的時間戳; - time2 : 4 字節
本字段必須包含先前發送的並被對端讀取的包的時間戳。可以再取當前時間戳,和C1或者S1當時取時間戳的方式一樣。 - random bytes: 1528 字節
本字段必須包含對端發送的隨機數據字段,即:如果當前是C2,需要截取S1發過來的隨機字段; 如果當前是S2,需要截取C1發過來的隨機字段。
複雜握手
+-------------+ +-------------+
| 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
[譯]握手示意圖