SIP協議解析與實現

2021-09-30 08:20:02 字數 4906 閱讀 7162

本文將按照rfc3261逐步的介紹sip協議,介紹了c和c++語言的實現,分析了osip庫的使用和實現。

第一章 概述

一 概述

sip協議是乙個基於應用層的會話控制協議。它可以建立、修改、終止多**會話(會議),也可以邀請參與者加入到乙個現有的會話。

由此可見,sip協議應該用來組合其它協議,從而實現完整的服務。但是,sip基礎的功能和操作不依賴於其它協議。

二 第乙個例子

下面引用rfc3261的例子來說明sip的基本功能,包括:定位終端,傳送通訊請求,協商會話引數,建立會話和撤銷建立的會話。圖1顯示了使用者alice和bob使用sip交換資訊的乙個典型的例子(每乙個訊息用字母f和乙個數字來標號,標號的前面有乙個簡短的訊息型別說明)。在這個例子中,alice使用乙個在她的pc機中的sip應用程式呼叫bob,bob使用他的sip**,這個sip**登入了網際網路。同時,請注意兩個sip**伺服器在alice和bob的會話的建立中起到的作用。

alice呼叫bob是使用他的sip識別符號。sip識別符號是一種uri(uniform resource identifier),稱之為sip uri。sip uri格式很象email位址,包含乙個使用者名稱和乙個主機名,如:sip:[email protected]。這裡biloxi.com是bob的sip服務提供者的網域名稱。alice的sip uri是:sip:[email protected]。sip也支援安全uri,叫做sips uri,例如,sips:[email protected]。乙個向sips uri的呼叫使用加密傳輸(也就是tls)來攜帶從呼叫者到被呼叫者所有的sip訊息。

sip是乙個與http協議很像的,請求/應答式的事務模型。每乙個事務最少由乙個要完成特定方法或功能的請求,和伺服器端的乙個應答組成。在這個例子中,這個事務從alice的軟**傳送乙個invite請求到bob的sip uri開始。invite是乙個sip訊息,它表示請求者alice想與bob通話。invite請求包含一些頭域。頭域被稱為屬性,可以提供關於這個訊息的額外資訊。關於頭域我們一會兒將會詳細說明它們。圖1中的invite資訊(f1)可能像這樣:

第一行文字是這個請求的方法名(invite)。後面的行是多個頭域。這裡只列出了最少需要的頭域。先在這裡對這些頭域做乙個簡要的介紹:

via頭域包含alice希望收到對於這個請求的應答的位址。也就是她告訴請求的接收者,應答應該傳送到 pc33.atlanta.com。後面的branch引數是這個事務的識別符號。

to頭域包含乙個顯示名(bob)和乙個sip uri或者sips uri,這裡是使用的sip uri(sip:[email protected])。這個sip uri就是這個請求要傳送的目標。

from頭域也包含乙個顯示名(alice)和乙個sip uri或者sips uri,這裡是使用的sip uri(sip:[email protected])來指出請求的發起人。這個頭域還包含了乙個tag引數,這個引數包含了乙個隨機字串(1928301774),這個字串的數字會被軟**自動增加,它主要起到鑑別的作用,後面還會說明它。

call-id頭域包含乙個全域性唯一識別符號來標識這次呼叫。這個識別符號使用乙個隨即字串和軟**所在的主機名(或者ip位址)一起生成。這樣,to頭域、from頭域和call-id這三個頭域就可以唯一的確定了alice和bob的這條點對點的通訊關係,並且將這個通訊關係交給乙個對話(dialog)來處理了。

cseq頭域(命令序列)包含乙個整數和乙個方法名字。在這個對話中每乙個新的請求都會增加這個整數的值,保證這個數值是有序的。

contact頭域包含乙個sip uri或者sips uri指出乙個能夠接觸到alice的直接路由,一般這個sip uri由使用者名稱和乙個完全限定網域名稱(fqdn)構成。因為許多終端系統沒有註冊網域名稱,所以也可以使用ip位址代替fqdn。via頭域向對方指出了這個請求的應答應該傳送到**,而contact頭域向對方指出了將來的請求應該傳送到**。

max-forwards頭域限制了在這個請求傳送到目的地的時候最多可以有多少跳。它包含乙個整數,在每一跳這個整數都會被減少。

content-type頭域描述訊息體的型別(在這個例子裡訊息體採用了sdp描述,但是訊息體內容沒有給出)。

content-length頭域指出了訊息體的位元組數。

在後面我們將完整的介紹sip頭域(rfc3261第20節)。

在會話中像**型別、編碼方式、取樣率等資訊都不使用sip描述,而是在訊息體中使用其它會話描述協議的格式。這個例子中採用了sdp描述(rfc2327)。

軟**不知道bob或者擁有biloxi.com網域名稱的sip伺服器,它將invite請求傳送給為alice提供服務的網域名稱為atlanta.com的sip伺服器。關於alice如何獲得atlanta.com sip伺服器的位址,可以使用由alice的軟**指定,或者使用dhcp探測到等方式。

atlanta.com sip伺服器是乙個sip**伺服器。乙個**伺服器接收sip請求,為請求的傳送者**請求。在這個例子中,**伺服器接收到invite請求後傳送乙個100應答(trying)給alice的軟**。100應答(trying)指出這個invite請求已經被**伺服器接收到,並且已被經進一步向目的地路由。sip中的應答使用3位數字表示,每乙個編號都表示乙個描述短語。這個100應答(trying)也同樣包含和invite請求一樣的to、from、call-id、cseq和via以及branch引數,這樣可以使alice的軟**知道這個應答是對應傳送的invite請求的。atlanta.com**伺服器定位出biloxi.com**伺服器(這可能需要通過網域名稱解析伺服器(dns)等實現,後面還會詳細講解)獲得了它的ip位址,並且準備把invite請求**給biloxi.com**伺服器。在**請求之前,atlanta.com**伺服器增加了乙個額外的via頭域,這個via頭域包含自己的位址(這時候這個invite請求的第乙個via頭域包含alice的軟**的位址)。biloxi.com**伺服器接收到這個invite請求,並且也傳送乙個100(trying)應答給atlanta.com**伺服器指出它已經接收到這個invite請求,並正在處理這個請求。biloxi.com**伺服器知道bob的ip位址(這可能需要定位服務),它又在這個invite請求中加入了乙個新的via頭域,值為自己的位址,然後它把這個invite請求傳送給bob的sip**。

bob的sip**接收到這個invite請求,傳送乙個180(ringing)應答,同時使用鈴聲通知bob有乙個來自alice的呼叫,讓bob決定是否接聽。這個180(ringing)應答反向經過這兩個**伺服器被傳送到alice。每乙個**伺服器使用via頭域決定向**傳送這個應答,並且把移除它自己新增的via頭域。這樣,雖然只有初始的invite請求傳送的時候使用了dns服務和定位服務,而這個180(ringing)應答沒有使用,同時**伺服器也不需要記錄整個通訊的狀態,但是這個應答還是能夠成功的傳送給請求的傳送者alice。

當alice的軟**接收到180(ringing)應答後,它將這個訊息告訴給alice,也許使用乙個聲音(彩鈴)或者在alice的螢幕上顯示乙個訊息。

在這個例子中,bob決定接聽**,當他按下接聽按鈕時,他的sip**傳送200(ok)應答表示接受了這個呼叫。這個200(ok)應答包含乙個訊息體,訊息體使用sdp描述bob準備和alice建立的會話的**型別等資訊。這樣,alice和bob交換了一次sip資訊:alice用invite請求傳送一次給bob,bob用200(ok)應答傳送一次給alice。這個交換實現了基本的協商能力和簡單的offer/answer模型。如果bob不希望接聽**,或者他現在正忙(接聽其它**),那麼他會傳送乙個錯誤應答而不是200(ok)應答。乙個錯誤應答將不會建立會話。 

bob傳送的200(ok)應答可能是這樣的:

應答的第一行包含乙個應答**(200)和乙個解釋短語(ok)。其它行就是應答的頭域。via,to,from,call-id和cseq頭域的值都從invite請求拷貝而來(這時候應該有3個via頭域,分別由alice的sip軟**,atlanta.com**伺服器,和biloxi.com**伺服器新增)。bob的sip**新增乙個tag引數到to頭域。以後所有的屬於這個對話的請求和應答都要包含這個tag引數。

當alice的軟**接收到這個200(ok)應答後,馬上停止響鈴並顯示呼叫已經被接聽了。最後,alice傳送乙個確認資訊(ack)給bob的sip**,表示自己收到了最終應答(200(ok))。這個例子中的最終應答由alice直接傳送給了bob,這是因為alice的軟**從contact頭域裡面可以得到bob的位址資訊。通過invita/200/ack的三步握手,sip會話就建立起來了。關於sip會話建立的詳細步驟請參看rfc3261第13節。

現在alice和bob的多**會話已經建立起來了,他們可以傳送通過sdp協商好的格式的**資料了。一般來說,**資料報的傳輸與sip訊息的傳輸採用不同的通訊方式。sip訊息大多通過**伺服器**,而**資料多使用點對點的傳輸。

在會話過程中,無論是alice還是bob決定改變這個**會話,都要通過傳送乙個re-invite請求。這個re-invite請求包含新的**描述(可能是sdp),它不會建立新的會話,而是修改當前已經存在的會話。對方接收到這個請求後,傳送乙個200(ok)同意這個改變,最後請求者傳送ack。如果對方不同意這個修改,可能會傳送乙個錯誤應答,比如488(不接受)。但是這個失敗應答不會使已存在的會話退出,而是繼續使用以前協商的**進行通訊。關於修改乙個會話的詳細說明,請參看rfc3261第14節。

最後,bob傳送bye訊息結束通話**。bye訊息直接傳送到alice的軟**。alice傳送200(ok)確定接收到了bye訊息,並且終止這個會話。bob不用傳送ack,因為ack只有在接收到對invite的應答時才被傳送。關於終止乙個會話更詳細的說明,請參看rfc3261第15節。

還有乙個問題就是關於biloxi.com伺服器如何獲得bob的位置。bob的sip**開機的時候會向乙個註冊伺服器傳送register訊息。register訊息的作用是將bob的sip uri或者sips uri與bob當前使用的**位址進行幫定,並將這個幫定資訊儲存到資料庫中,這被稱之為定位服務(location service)。biloxi.com**伺服器使用定位服務獲得bob的位址。註冊伺服器、**伺服器、定位伺服器都是邏輯上的伺服器,而不是物理上的伺服器,所以他們可以位於同一臺伺服器上。

Sip協議棧 事務層的設計與實現

乙個事務是客戶傳送的乙個請求事務 通過通訊層 傳送到乙個伺服器事務,連同伺服器事務的所有的該請求的應答傳送回客戶端事務。事務層處理應用服務層的重發,匹配請求的應答,以及應用服務層的超時。任何乙個使用者 客戶端 user agent client uac 完成的事情都是由一組事務構成的。通常乙個sip...

SIP協議詳解

sip 協議概念 會話啟動協議sip session initiation protocol 是乙個在ip網路上進行多 通訊的應用層控制協議,它被用來創 建 修改 和終結乙個或多個參加者參加的會話程序。sip協議可用於發起會話,也可以用於邀請成員加入已經用其它方式建立的會話。sip協議透明地支援名字...

SIP協議初探

1.sip協議的定義 2.sip協議特點 位於應用層,作用 主要控制通訊雙方的信令。h.323和sip分別是通訊領域與網際網路兩大陣營推出的協議。h.323企圖把ip 當作是眾所周知的傳統 只是傳輸方式發生了改變,由電路交換變成了分組交換。而sip協議側重於將ip 作為網際網路上的乙個應用,較其它應...