SIP消息由三部分組成,即:開始行(start line)、消息頭(header)、正文(body)
Start-line:
請求行Request-line
消息為 request消息時使用request-line
Request-Line = Method SP Request-URI SP SIP-Version CRLF
狀態行Status-line
消息為響應消息時使用Status-line
Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
請求行Request-line由消息方法+Request-URI+SIP版本組成:
消息方法: 以下列出了六種消息方法
REGISTER: 注冊聯系信息
INVITE: 發起會話請求
ACK:對 INVITE 請求的響應的確認
CANCEL: 取消請求
BYE: 終結會話
OPTIONS: 查詢服務器能力
Request-URI: 指示請求的用戶或者服務的地址信息
SIP-version: 請求和響應消息都需要包含SIP版本信息
舉例: INVITE sip:bob@zte.com SIP/2.0
狀態行Status-line由SIP版本+狀態碼+原因短語組成
舉例: SIP/2.0 200 OK
---------------------------------------------------------------
消息頭:
格式: 字段名(field-name): 參數值(field-value)
Example: REGISTER sip:registrar.zte.com SIP/2.0
Via: SIP/2.0/UDP bobspc.zte.com:5060;branch=z9hG4bKnashds7
Max-Forwards: 70
To: Bob <sip:bob@zte.com>
From: Bob <sip:bob@zte.com>;tag=456248
Call-ID: [email=843817637684230@998sdasdh09]843817637684230@998sdasdh09[/email]
CSeq: 1826 REGISTER
Contact: <sip:bob@192.0.2.4>
Expires: 7200
Content-Length: 0
上面via、max-forwards、to、from、call-id等這些都是些常有的頭域,SIP的頭域總共有44個之多。
sip事務的概念:一個sip請求以及由它觸發的一系列應答(包括臨時應答和一個最終應答)。
sip請求有6種(核心規范定義的,也有擴展),也叫6個方法(Method字段標識):INVITE, ACK, OPTIONS, BYE, CANCEL, REGISTER
sip 請求的格式包括請求行(如INVITE sip:192.168.101.30 SIP/2.0),sip應答的格式包括狀態行(如SIP/2.0 100 Trying);sip應答的狀態碼從100到699,其中100~199是臨時(provisional)應答。
INVITE請求是三次握手機制,其他請求都采用兩次握手機制。
CANCEL 請求用於取消懸而未決的事務,我的理解是一方發出INVITE,但是另一方始終沒有做出應答,發出200OK消息(超過了默認的振鈴時長),那么UAC會 自動發出一個CANCEL請求,UAS返回200OK,並且同時發出487狀態碼的應答,UAC再對收到的487消息發出ACK確認,即最開始的 INVITE和487以及ACK構成三次握手。
OPTIONS請求用於詢問服務器的性能情況,包括這個服務器所支持的方法(可能會有擴展方法)和會話描述協議。
代理服務器的三種類型:保留呼叫狀態代理、保留狀態代理、不保留狀態代理。這三種類型的代理在處理能力和所占用資源上有差別,在代理分發中我們采用網絡核心無狀態,而在流量較小的網絡邊界采用智能性高的保留(呼叫)狀態服務器處理路由。
sip消息編碼采用文本方式(即使用字符串),相對的是二進制的編碼方式,前者易於調試和擴展,后者則有利於節省帶寬。
sip標題頭:
CALL-ID 字 段用於標識一個特定邀請以及與這個邀請相關的所有后續事務(即標識一個會話),比如一方發起邀請加入一個國際象棋的會話,那么INVITE請求以及應答, BYE請求以及應答都共享一個CALL-ID,因為這兩個事務都屬於一個特定邀請。而兩個用戶之間可以同時存在多個邀請(比如在下象棋的同時發起聊天的邀 請),那么一個邀請中的后續事務將通過這個邀請特有的CALL-ID來區分,如一方發出BYE消息來結束聊天,但是下棋仍然進行中,那么另一方將根據 BYE消息的CALL-ID來確定要結束的究竟是哪一個會話。
CSeq 字段是用來給同一個會話中的 事務進行排序的。可以理解為,會話由CALL-ID來標識,會話中的事務則由CSeq標識。除了ACK請求和CANCEL請求,INVITE之后的請求中 CSeq字段的數字是最初請求(INVITE)的CSeq遞增的結果。而ACK和CANCEL請求則擁有與它所確認(取消)的請求相同的CSeq數字部 分,只是方法名不同。
(sip標題頭續)
Contact 字段是被呼叫方發送200OK消息時帶上的,包含了被叫方的真實IP,這樣sip服務器在路由第一個INVITE請求之后就可以被卸載掉(越過),不再需要存在於信令路徑中。
Recode-Route和Route字 段是用來使sip服務器保留在每次請求中,不被繞過。Record-Route字段由信令路徑上的服務器添加(每經過一個信令路徑上必須存在的代理,就添 加一個Record-Route標題頭),maddr參數包含該代理的IP地址。被叫方發出的200OK應答包含Record-Route和 Contact字段(Record-Route可能有多個),呼叫方收到200OK后根據這兩個字段創建用於后續請求的Route標題頭(可能有多個), 其包含的是信令路徑上的下一跳的下一跳的(hehe,有點別扭,不過意思是對的)真實IP。
To 字段 總是包含被呼叫方的地址(通過sip代理時是公用地址,點對點時是真實ip),要注意的是區別該標題頭和sip消息請求行中的Request-URI。 To在信令路徑中不會被代理改變,然而Request-URI包含的是信令路徑中下一跳的地址,因此在路途中被每個代理改變。
Via 字 段存儲所有處理請求的代理地址(包括用戶代理和sip代理),它可以用來檢測路由循環,也用於使應答消息經過請求消息來時相同的路徑(方向相反)。因此, 在請求消息發送時,via標題頭的數量是隨着跳數逐漸增加的,而應答消息返回時,via標題頭的數量則逐漸遞減(每經過一跳則剝離一個有它自己地址的 Via標題頭)。
(sip標題頭完)
sip消息可能含有消息體(一個或多個),通常是會話描述符,也可以是照片或其他附件。一般情況下,消息體只對UA有意義,因此可被端到端加密。有時候,sip代理處於控制的原因也需要檢查被交換媒體的信息。
NVITE事務:
SIP使用UDP傳輸協議來傳送INVITE消息時,要使用逐 跳重傳機制保證INVITE的最終傳送,即用戶代理UA和sip代理proxy都要保證INVITE到達下一跳,下一跳收到時會返回一個臨時應答 (proxy返回100Trying,UA返回100Trying和180ringing),代理在限定時間內收不到應答即會重傳INVITE。
臨時應答(100~199)用於阻止逐跳INVITE重傳,沒有端到端的可靠傳輸,也就是說當被叫方返回180應答時,如果在路徑中途丟失,也不會重傳。
最終應答(200~699)能被保證到達它們想要去的目的地。
成 功應答(200~299)被可靠地傳送到呼叫方UA,但不是使用逐跳重傳機制。只有呼叫方UA能為最終成功應答發送一個ACK(直接發送到被叫方UA), 如果成功應答在路徑中途丟失或者UA發出的ACK丟失,那么被叫方會在限定時間內收不到ACK時重新發送最終應答,直到收到ACK的確認。
非成功最終應答(300~699)使用和INVITE一樣的逐跳機制。被叫方用戶代理將持續重傳非成功應答(給前一跳),直到收到ACK為止(proxy也可以為非成功應答發送ACK)。
CANCEL事務:
CANCEL事務與INVITE事務都是逐跳事務,但是處理方法不同,路徑上的每一個代理收到CANCEL請求時,都會發送一個最終應答來響應(而不是發出臨時應答),並且向下一跳發送一個CANCEL請求。
實例說明:
抓取“成功注冊”,“呼叫--通話” ,“掛斷”“注銷”四種情況做典型包的分析。
Ø 注冊流程:
以上是REGISTER包。
我們可以看到在注冊的時候,終端會向代理服務器59.64.135.22發送REGISTER請求注冊。
以上是REGISTEROK包。服務器返回200 OK,表示注冊成功。
Ø 基本呼叫建立過程:
以上是INVITE包。我們可以看到在發起呼叫初期,終端向825002發出Invite的呼叫請求。
以上是Trying包,說明終端825003正在試着連通服務器,進一步轉接到825002.
由於設置了自動接聽,所以此次通話沒有振鈴的包。
這是ACK包,代表確認信號。
Ø 正常呼叫釋放過程:
以上是BYE包。這是825002掛斷后服務器向825003發送的釋放呼叫信號。
Ø 注銷流程:
以上是825003注銷的包,我們注意到expires=0這說明是注銷。