SIP 協議詳解

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

 SIP協議Session Model

主叫方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收到被叫方B200 OK響應後,向被叫方B發送一個ACK,會話創建;
  • 步驟18~20:會話結束後,任何參與者(A或B)均可以發送一個BYE請求來終止會話;
  • 步驟21~23:主叫方A發送200 OK響應來確認BYE,會話終止。

注:以上的整個流程稱之爲一個Dialogui

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/cpimmessage/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消息爲例:

Pager Model

  • 步驟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爲例:

Pager Model

步驟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 ==========

wx_gzh.jpg

原文出處:https://www.cnblogs.com/xiaxveliang/p/12434170.html

相關文章
相關標籤/搜索