rtmp协议分析(三次握手)
RTMP詳細分析(Message 消息,Chunk分塊)
librtmp分析(發(fā)送數(shù)據(jù)包處理)
librtmp分析(接收數(shù)據(jù)包處理)
RTMP協(xié)議是Real Time Message Protocol(實時信息傳輸協(xié)議)的縮寫,它是由Adobe公司提出的一種應
用層的協(xié)議,用來解決多媒體數(shù)據(jù)傳輸流的多路復用(Multiplexing)和分包(packetizing)的問題。隨
著VR技術的發(fā)展,視頻直播等領域逐漸活躍起來,RTMP作為業(yè)內廣泛使用的協(xié)議也重新被相關開發(fā)者重
視起來。
目錄
- 1、介紹:
- 2.1、握手:
- 2.2、握手過程:
- 3.1 、C0和S0格式(簡單握手):
- 3.2 、C1和S1格式(簡單握手):
- 3.3 、C2和S2格式(簡單握手):
- 4、復雜握手:
1、介紹:
RTMP協(xié)議是應用層協(xié)議,是要靠底層可靠的傳輸層協(xié)議(通常是TCP)來保證信息傳輸?shù)目煽啃缘摹T?br /> 基于傳輸層協(xié)議的鏈接建立完成后,RTMP協(xié)議也要客戶端和服務器通過“握手”來建立基于傳輸層鏈接之
上的RTMP Connection鏈接,在Connection鏈接上會傳輸一些控制信息,如
SetChunkSize,SetACKWindowSize。其中CreateStream命令會創(chuàng)建一個Stream鏈接,用于傳輸具體的
音視頻數(shù)據(jù)和控制這些信息傳輸?shù)拿钚畔ⅰTMP協(xié)議傳輸時會對數(shù)據(jù)做自己的格式化,這種格式的消
息我們稱之為RTMP Message,而實際傳輸?shù)臅r候為了更好地實現(xiàn)多路復用、分包和信息的公平性,發(fā)送
端會把Message劃分為帶有Message ID的Chunk,每個Chunk可能是一個單獨的Message,也可能是
Message的一部分,在接受端會根據(jù)chunk中包含的data的長度,message id和message的長度把
chunk還原成完整的Message,從而實現(xiàn)信息的收發(fā)。
2.1、握手:
一個 RTMP 連接以握手開始。RTMP 的握手不同于其他協(xié)議? RTMP 握手由三個固定
長度的塊組成,而不是像其他協(xié)議一樣的帶有報頭的可變長度的塊。
客戶端 (發(fā)起連接請求的終端) 和服務器端各自發(fā)送相同的三塊。
客戶端發(fā)送的這些塊稱為C0、 C1 和 C2,服務器端發(fā)送的這些塊稱為 S0、
S1 和 S2。
2.2、握手過程:
本身并沒有規(guī)定這6個Message的具體傳輸順序,但RTMP協(xié)議的實現(xiàn)者需要保證這幾點:
客戶端要等收到S1之后才能發(fā)送C2
客戶端要等收到S2之后才能發(fā)送其他信息(控制信息和真實音視頻等數(shù)據(jù))
服務端要等到收到C0之后發(fā)送S1
服務端必須等到收到C1之后才能發(fā)送S2
服務端必須等到收到C2之后才能發(fā)送其他信息(控制信息和真實音視頻等數(shù)據(jù))
理論上來講只要滿足以上條件,如何安排6個Message的順序都是可以的,但實際實現(xiàn)中為了在保證握手
的身份驗證功能的基礎上盡量減少通信的次數(shù),一般的發(fā)送順序是這樣的,這一點可以通過wireshark抓推流包進行驗證:
握手流程圖:
Uninitialized (未初始化):協(xié)議的版本號在這個階段被發(fā)送。客戶端和服務器都是。
uninitialized (未初始化)狀態(tài)。之后客戶端在數(shù)據(jù)包 C0 中將協(xié)議版本號發(fā)出。如果服務器
支持這個版本,它將在回應中發(fā)送S0 和 S1。如果不支持,服務器會才去適當?shù)男袨檫M
行響應。在 RTMP 協(xié)議中,這個行為就是終止連接。
Version Sent (版本已發(fā)送):在未初始化狀態(tài)之后,客戶端和服務器都進入 Version Sent
(版本已發(fā)送) 狀態(tài)。客戶端會等待接收數(shù)據(jù)包 S1 而服務器在等待 C1。一旦拿到期待的包,
客戶端會發(fā)送數(shù)據(jù)包 C2 而服務器發(fā)送數(shù)據(jù)包 S2。 (客戶端和服務器各自的)狀態(tài)隨即變?yōu)?br /> Ack Sent (確認已發(fā)送 )。
Ack Sent (確認已發(fā)送):客戶端和服務器分別等待 S2 和 C2。
Handshake Done (握手結束):客戶端和服務器可以開始交換消息了。
3.1 、C0和S0格式(簡單握手):
C0 和 S0 包都是一個單一的八位字節(jié),以一個單獨的八位整型域進行處理:
版本( 八位):在 C0 中,這一字段指示出客戶端要求的 RTMP 版本號。
在 S0 中,這一字段指示出服務器端選擇的 RTMP 版本號。版本號基本都是3。
0、1、2 這三個值是由早期其他產品使用的,是廢棄值。
4 - 31 被保留為RTMP 協(xié)議的未來實現(xiàn)版本使用。
32 - 255 不允許使用 (以區(qū)分開 RTMP 和其他常以一個可打印字符開始的文本協(xié)議)。
無法識別客戶端所請求版本號的服務器應該以版本 3 響應, (收到響應的) 客戶端可以選擇降低到版本 3,或者放棄握手。
3.2 、C1和S1格式(簡單握手):
C1 和 S1 數(shù)據(jù)包的長度都是 1536 字節(jié),分布如下:
Time (四個字節(jié)):這個字段包含一個 timestamp,用于本終端發(fā)送的所有后續(xù)塊的時間
起點。這個值可以是 0。
Zero (四個字節(jié)):這個字段必須都是 0。
Random data (1528 個字節(jié)):這個字段可以包含任意值。終端需要區(qū)分出響應來自它發(fā)
起的握手還是對端發(fā)起的握手,這個數(shù)據(jù)應該發(fā)送一些足夠隨機的數(shù)。這個不需要對隨機數(shù)進行加密保護,也不需要動態(tài)值。
3.3 、C2和S2格式(簡單握手):
C2 和 S2 數(shù)據(jù)包長度都是 1536 個節(jié),基本就是 S1 和 C1 的副本。分布如下:
Time (四個字節(jié)):這個字段必須包含終端在 S1 (給 C2) 或者 C1 (給 S2) 發(fā)的
timestamp。
Time2 (四個個節(jié)):這個字段必須包含終端先前發(fā)出數(shù)據(jù)包 (s1 或者 c1) timestamp。
Random echo (1528 個字節(jié)):這個字段必須包含終端發(fā)的 S1 (給 C2) 或者 S2 (給 C1)
的隨機數(shù)。
4、復雜握手:
復雜握手主要是增加了更嚴格的驗證。
主要是將簡單握手中1528Bytes隨機數(shù)的部分平均分成兩部分,
一部分764Bytes存儲public key(公共密鑰),另一部分
764Bytes存儲digest(密文, 32字節(jié))。
另外, 復雜握手還有一個明顯的特征就是: Version部分不為0,
服務器端可根據(jù)這個來判斷是否簡單握手或復雜握手。
總結
以上是生活随笔為你收集整理的rtmp协议分析(三次握手)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搭建srs服务器(rtmp)
- 下一篇: 摩尔庄园草莓音乐节怎么参加