一 概述
SIP 协议是一个基于应用层的会话控制协议。它可以创建、修改、终止多媒体会话 ( 会议 ) ,也可以邀请参与者加入到一个现有的会话。
因为 SIP 是一个基于应用层的协议,所以它不是一套完整的通讯系统方案,它需要和其它的方案或者协议结合起来实现整套系统。例如,实时传输协议 (RTP)(RFC1889) 用来传输音视频等实时的流媒体数据。实时流协议 (RTSP)(RFC2326) 用来控制媒体流的传递。媒体网关控制协议 (MEGACO)(RFC3015) 用来控制 PSTN 网关。
由此可见, SIP 协议应该用来组合其它协议,从而实现完整的服务。但是, SIP 基础的功能和操作不依赖于其它协议。
二 第一个例子
图1
下面引用 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:bob@biloxi.com 。 这里 biloxi.com 是 Bob 的 SIP 服务提供者的域名。 Alice 的 SIP URI 是: sip: alice@atlanta.com 。 SIP 也支持安全 URI ,叫做 SIPS URI ,例如, sips: bob@biloxi.com 。 一个向 SIPS URI 的呼叫使用加密传输 ( 也就是 TLS) 来携带从呼叫者到被呼叫者所有的 SIP 消息。
SIP 是一个与 HTTP 协议很像的,请求/应答式的事务模型。每一个事务最少由一个要完成特定方法或功能的请求,和服务器端的一个应答组成。在这个例子中,这个事 务从 Alice 的软电话发送一个 INVITE 请求到 Bob 的 SIP URI 开始。 INVITE 是一个 SIP 消息,它表示请求者 Alice 想与 Bob 通话。 INVITE 请求包含一些头域。头域被称为属性,可以提供关于这个消息 的额外信息。关于头域我们一会儿将会详细说明它们。图 1 中的 INVITE 信息 (F1) 可能像这样:
INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142
(Alice's SDP not shown)
第一行文本是这个请求的方法名 (INVITE) 。后面的行是多个头域。这里只列出了最少需要的头域。先在这里对这些头域做一个简要的介绍:
Via 头域包含 Alice 希望收到对于这个请求的应答的地址。也就是她告诉请求的接收者,应答应该发送到 pc33.atlanta.com 。后面的 branch 参数是这个事务的标识符。
To 头域包含一个显示名 (Bob) 和一个 SIP URI 或者 SIPS URI ,这里是使用的 SIP URI(sip:bob@biloxi.com ) 。这个 SIP URI 就是这个请求要发送的目标。
From 头域也包含一个显示名 (Alice) 和一个 SIP URI 或者 SIPS URI ,这里是使用的 SIP URI(sip:alice@atlanta.com ) 来指出请求的发起人。这个头域还包含了一个 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) 应 答可能是这样的:
SIP/2.0 200 OK
Via: SIP/2.0/UDP server10.biloxi.com
;branch=z9hG4bKnashds8;received=192.0.2.3
Via: SIP/2.0/UDP bigbox3.site3.atlanta.com
;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
Via: SIP/2.0/UDP pc33.atlanta.com
;branch=z9hG4bK776asdhds ;received=192.0.2.1
To: Bob <sip:bob@biloxi.com>;tag=a6c85cf
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:bob@192.0.2.4>
Content-Type: application/sdp
Content-Length: 131
(Bob's SDP not shown)
应答的第一行包含一个应答代码 (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 的地址信 息。通过 INVITE/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 的地址。注册服务器、代理服务器、定位 服务器都是逻辑上的服务器,而不是物理上的服务器,所以他们可以位于同一台服务器上。