SIP 協議詳解
2013年參與過一個「視頻通信的App」項目,使用Sip協議通訊。當時通訊協議這塊不是本身負責,加上時間緊、任務重等方面的緣由,一直未對Sip協議進行過深刻的瞭解。 2020年春天疫情突發,宅在家裏終於有了空餘時間。這裏來詳細瞭解一下Sip協議。html
如下內容大體分爲如下幾個部分:數據庫
- 協議簡介
- 兩種Sip會話模式Session Model與Pager Model;
- Sip 消息體結構
- Sip 消息舉例
1、Sip協議簡介:
SIP(Session Initiation Protocol,會話初始協議)是由IETF(Internet Engineering Task Force,因特網工程任務組)制定的多媒體通訊協議。普遍應用於CS(Circuit Switched,電路交換)、NGN(Next Generation Network,下一代網絡)以及IMS(IP Multimedia Subsystem,IP多媒體子系統)的網絡中,能夠支持並應用於語音、視頻、數據等多媒體業務
,同時也能夠應用於Presence(呈現)、Instant Message(即時消息)等特點業務。能夠說,有IP網絡的地方就有SIP協議的存在。 SIP是相似於HTTP
,SIP能夠減小應用特別是高級應用的開發時間。因爲基於IP協議的SIP利用了IP網絡
,固定網運營商也會逐漸認識到SIP技術對於他們的遠意義。服務器
2、Sip消息的兩種會話模式
在Sip IM通訊應用過程當中,通常存在着兩種會話模式:網絡
- Session Model
- Pager Model
2.一、Session Model
會話中,對於消息體內容大於1300字節
時,通常採用Session Model
。其會話創建過程以下圖所示:app
主叫方A呼叫被叫方B:dom
- 步驟1:
主叫方A
發送INVITE
請求到代理服務器
; - 步驟2:
代理服務器
發送100 Trying 響應主叫方A
; - 步驟3~6:
代理服務器
搜索被叫方B
的地址,獲取地址後轉發INVITE請求; - 步驟7~9:
被叫方B
生成的180 振鈴響應,返回給主叫方A
; - 步驟10~12:
被叫方B
生成的200 OK響應,返回給主叫方A
; - 步驟13~17:
主叫方A
收到被叫方B
200 OK響應後,向被叫方B
發送一個ACK,會話創建; - 步驟18~20:會話結束後,任何參與者(A或B)均可以發送一個BYE請求來終止會話;
- 步驟21~23:
主叫方A
發送200 OK響應來確認BYE,會話終止。
注:以上的整個流程稱之爲一個Dialog
ui
2.二、Pager Model
在Sip消息中,對於消息體不大於1300字節
時,通常採用Pager Model
。Sip消息通訊中採用MESSAGE
方法,MESSAGE
方法自己並不創建Dialog
,在多數應用中,每條IM消息都是獨立的,頗似分頁消息。spa
2.2.1 MESSAGE方法的由來
RFC3428
對Sip協議進行了擴展,在Sip協議中增長了MESSAGE
請求方法。採用Pager Model進行通訊,傳遞不超過1300字節的數據。MESSAGE方法詳細可參考 「SIP-RFC3428」 https://tools.ietf.org/html/rfc3428 。.net
2.2.2 MESSAGE方法消息體
當User1想給User2發送IM消息時,只需構造一個MESSAGE,發出去便可。 對於其消息體body
能夠是任何MIME
格式。但必須支持plain/text
格式,能夠選擇支持message/cpim
、message/sdp
格式,可能用message/cpim
會好一點,由於已有的IM系統標準是message/cpim
格式。3d
注:想了解CPIM消息格式的同窗可參考:CPIM 消息格式:https://xiaxl.blog.csdn.net/article/details/104718006 注:想了解SDP消息格式的同窗可參考:SDP 消息格式:https://xiaxl.blog.csdn.net/article/details/104723834
2.2.3 Pager Model請求流程以下
以User1向User2發送MESSAGE消息爲例:
- 步驟1:
User1
發送MESSAGE
請求到代理服務器
; - 步驟2:
代理服務器
轉發User1
的MESSAGE請求給USER2
; - 步驟3:
User2
收到User1
的消息後,回覆200 OK給代理服務器
; - 步驟7~9:
代理服務器
轉發200 OK回覆給User1
3、SIP消息體格式
SIP消息體結構
與Http協議結構
類似,均由三部分組成:
- 請求行(request-line) or 狀態行(status-line)
- 消息頭(header)
- 正文(body)
3.一、請求行
請求行格式:Method Request-URI SIP-Version CRLF
請求行舉例:INVITE sip:bob@zte.com SIP/2.0 /r/n
Method 如下列出了幾種消息Method方法
:
Method | 方法說明 |
---|---|
REGISTER | 註冊聯繫信息 |
INVITE | 發起會話請求 |
ACK | INVITE 請求的響應的確認 |
CANCEL | 取消請求 |
BYE | 終結會話 |
OPTIONS | 查詢服務器能力 |
MESSAGE | RFC3428對Sip協議的擴展,增長了MESSAGE方法。採用Pager Model進行通訊,傳遞不超過1300字節的數據。MESSAGE方法詳細可參考 「SIP-RFC3428」 https://tools.ietf.org/html/rfc3428 |
Request-URI 指示請求的用戶或者服務的地址信息
SIP-Version 請求和響應消息都須要包含SIP版本信息
3.二、狀態行
狀態行格式: SIP-Version Status-Code Reason-Phrase CRLF
狀態行舉例:SIP/2.0 200 OK /r/n
Status-Code狀態碼: 狀態代碼由3位數字組成,表示請求是否被理解或被知足。 狀態代碼的第一個數字定義了響應的類別,後面兩位沒有具體的分類
。
第一個數字有五種可能的取值:
狀態碼 | 含義 |
---|---|
1xx: | 臨時響應、表示請求消息正在被處理 |
2xx | 成功響應、表示請求已被成功接收徹底理解並接收 |
3xx | 重定向響應、表示需採起進一步完成請求 |
4xx | 客戶機錯誤、表示請求消息中包含語法錯誤信息或服務器沒法完成客戶機的請求 |
5xx | 服務器錯誤、表示服務器沒法合法完成請求 |
6xx | 全局故障 、表示任何服務器都沒法完成該請求 |
經常使用的狀態碼舉例:
狀態碼 | msg | 含義 |
---|---|---|
100 | Trying | 試呼叫 |
180 | Ringing | 振鈴 |
181 | Call is Being Forwarded | 呼叫正在前轉 |
200 | OK | 成功響應 |
302 | Moved Temporarily | 臨時遷移 |
400 | Bad Request | 錯誤請求 |
401 | Unauthorized | 未受權 |
403 | Forbidden | 禁止 |
404 | Not Found | 用戶不存在 |
408 | Request Timeout | 請求超時 |
480 | Temporarily Unavailable | 暫時無人接聽 |
486 | Busy Here | 線路忙 |
504 | Server Time-out | 服務器超時 |
600 | Busy Everywhere | 全忙 |
3.三、消息頭
發送MESSAGE
消息給user2
MESSAGE sip:user2@domain.com SIP/2.0 Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse Max-Forwards: 70 From: sip:user1@domain.com;tag=49583 To: sip:user2@domain.com Call-ID: asd88asd77a@1.2.3.4 CSeq: 1 MESSAGE Content-Type: text/plain Content-Length: 18 user2, come here.
Header 字段含義說明:
Header | 含義說明 | 舉例 |
---|---|---|
Call-ID | 由本地設備(Client)生成,全局惟一,每次呼叫這個值惟一不變 | Call-ID: asd88asd77a@1.2.3.4 |
From | 表示請求的發起者 | From: sip:user1@domain.com;tag=49583 |
To | 表示請求的接收者 | To: sip:user2@domain.com |
Via | Via頭域是被服務器插入request中,用來檢查路由環的,而且可使response根據via找到返回的路 | Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse |
Max-Forwards | 用於表示這個包最多能夠傳送多少跳,每通過一跳都會減一當Max-Forwards==0系統會返回483。默認爲70 | Max-Forwards: 70 |
Contact | 包含源的URI信息,用來給響應方直接和源創建鏈接用 | Contact: sip:192.168.100.1:1111 |
Content-Type | 指明消息體的類型 (SDP會話描述協議) | Content-Type: text/plain;Content-Type: application/sdp; Content-Type: application/cpim; |
Content-Length | 指明消息體的字節大小 | Content-Length: 18 |
4、SIP消息舉例
這裏舉兩個例子:
- MESSAGE消息(Pager Mode)
- REGISTER消息
4.一、MESSAGE消息(Pager Model)
以User1
發送MESSAGE
消息給user2
爲例:
步驟1:User1
發送MESSAGE
請求到代理服務器
MESSAGE sip:user2@domain.com SIP/2.0 Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse Max-Forwards: 70 From: sip:user1@domain.com;tag=49583 To: sip:user2@domain.com Call-ID: asd88asd77a@1.2.3.4 CSeq: 1 MESSAGE Content-Type: text/plain Content-Length: 18 user2, come here.
步驟2:代理服務器
轉發User1
的MESSAGE請求給USER2
代理服務器
收到步驟1
請求,到數據庫中查找User2
(註冊過程當中生成數據庫),隨後生成步驟2
的數據。
MESSAGE sip:user2@domain.com SIP/2.0 Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse; received=1.2.3.4 Max-Forwards: 69 From: sip:user1@domain.com;tag=49394 To: sip:user2@domain.com Call-ID: asd88asd77a@1.2.3.4 CSeq: 1 MESSAGE Content-Type: text/plain Content-Length: 18 user2, come here.
步驟3:User2
收到User1
的消息後,回覆200 OK給代理服務器
直接回應(200-OK) 沒有Body,也不攜帶Contact頭域
SIP/2.0 200 OK Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds; received=192.0.2.1 Via: SIP/2.0/TCP user1pc.domain.com;;branch=z9hG4bK776sgdkse; received=1.2.3.4 From: sip:user1@domain.com;tag=49394 To: sip:user2@domain.com;tag=ab8asdasd9 Call-ID: asd88asd77a@1.2.3.4 CSeq: 1 MESSAGE Content-Length: 0
步驟4:代理服務器
轉發200 OK回覆給User1
代理服務器
收到回覆後,去掉最頂端的Via
,轉發以下消息給User1
SIP/2.0 200 OK Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse; received=1.2.3.4 From: sip:user1@domain.com;;tag=49394 To: sip:user2@domain.com;tag=ab8asdasd9 Call-ID: asd88asd77a@1.2.3.4 CSeq: 1 MESSAGE Content-Length: 0
4.二、REGISTER消息
首先舉例一個非鑑權註冊消息。
4.2.1 非鑑權註冊消息
192.168.2.161
機器發送註冊消息給192.168.2.89
服務器:
REGISTER sip:192.168.2.89 SIP/2.0 Via: SIP/2.0/UDP 192.168.2.161:10586 Max-Forwards: 70 From: <sip:01062237496@192.168.2.89>;tag=ca04c1391af3429491f2c4dfbe5e1b2e;epid=4f2e395931 To: <sip:01062237496@192.168.2.89> Call-ID: da56b0fab5c54398b16c0d9f9c0ffcf2@192.168.2.161 CSeq: 1 REGISTER Contact: <sip:192.168.2.161:10586>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER" User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005) Event: registration Allow-Events: presence Content-Length: 0
當註冊成功(回送200 OK)時,服務器發送的res消息參考以下:
SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.2.161:10586 From: <sip:01062237496@192.168.2.89>;tag=ca04c1391af3429491f2c4dfbe5e1b2e;epid=4f2e395931 To: <sip:01062237496@192.168.2.89>;tag=-00834-14d0805b62bc026d Call-ID: da56b0fab5c54398b16c0d9f9c0ffcf2@192.168.2.161 CSeq: 1 REGISTER Allow: INVITE,ACK,OPTIONS,BYE,CANCEL,REGISTER,INFO,UPDATE,PRACK,REFER,SUBSCRIBE,NOTIFY,MESSAGE Contact: sip:192.168.2.161:10586 Content-Length: 0 Expires: 3600
4.2.2 鑑權註冊消息
當須要鑑權註冊時
- 請求端192.168.2.161發送註冊消息給192.168.2.89服務器
- 服務器對192.168.2.161發送「401 Unauthorized」信息給請求端,提示請求端須要帶上鑑權信息從新註冊
- 請求端帶上鑑權信息後(帶有「Authorization」頭字段)從新向服務器註冊
- 服務器驗證鑑權頭的正確性,若是鑑權成功,給請求端發送200 OK消息。若失敗,繼續發送401消息。
請求端192.168.2.161
發送註冊消息給192.168.2.89
服務器
REGISTER sip:192.168.2.89 SIP/2.0 Via: SIP/2.0/UDP 192.168.2.161:8021 Max-Forwards: 70 From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d To: <sip:01062237493@192.168.2.89> Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161 CSeq: 1 REGISTER Contact: <sip:192.168.2.161:8021>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER" User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005) Event: registration Allow-Events: presence Content-Length: 0
服務器對192.168.2.161
發送401 Unauthorized
信息給請求端,提示請求端須要帶上鑑權信息從新註冊:
SIP/2.0 401 Unauthorized Via: SIP/2.0/UDP 192.168.2.161:8021 From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d To: <sip:01062237493@192.168.2.89>;tag=-001893-38ba013ba3dde36e Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161 CSeq: 1 REGISTER Allow: INVITE,ACK,OPTIONS,BYE,CANCEL,REGISTER,INFO,UPDATE,PRACK,REFER,SUBSCRIBE,NOTIFY,MESSAGE Contact: <sip:192.168.2.89:14010> Content-Length: 0 WWW-Authenticate: Digest realm="192.168.2.89", qop="auth", nonce="e17d377c3d2d9c343e26576a7fd04738481dfc10", opaque="", stale=FALSE, algorithm=MD5
請求端192.168.2.161
經過Authorization
頭字段帶上鑑權頭信息,發送一個新的REGISTER消息:
REGISTER sip:192.168.2.89 SIP/2.0 Via: SIP/2.0/UDP 192.168.2.161:8021 Max-Forwards: 70 From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d To: <sip:01062237493@192.168.2.89> Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161 CSeq: 2 REGISTER Contact: <sip:192.168.2.161:8021>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER" User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005) Authorization: Digest username="01062237493", realm="192.168.2.89", qop=auth, algorithm=MD5, uri="sip:192.168.2.89", nonce="e17d377c3d2d9c343e26576a7fd04738481dfc10", nc=00000001, cnonce="12660455546344082314666316435946", response="f57e47ce03162293b9ced07362ce2b79" Event: registration Allow-Events: presence Content-Length: 0
服務器驗證鑑權頭的正確性,若是鑑權成功,給請求端發送200 OK消息。若失敗,繼續發送401消息
SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.2.161:8021 From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d To: <sip:01062237493@192.168.2.89>;tag=-001894-a5eb977c8969aa51 Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161 CSeq: 2 REGISTER Allow: INVITE,ACK,OPTIONS,BYE,CANCEL,REGISTER,INFO,UPDATE,PRACK,REFER,SUBSCRIBE,NOTIFY,MESSAGE Contact: sip:192.168.2.161:8021 Content-Length: 0 Expires: 3600
5、參考:
Sip—RFC3428:https://tools.ietf.org/html/rfc3428
MSRP—RFC4975:https://tools.ietf.org/html/rfc4975
CPIM消息格式:https://www.xuebuyuan.com/1929719.html
========== THE END ==========
原文出處:https://www.cnblogs.com/xiaxveliang/p/12434170.html