Sip协议的全称是会话初始协议(Session Initiation Protocol),用于控制发起、修改、终结交互式多媒体会话的信令协议。在现在的通信领域,越来越多的电信供应商都在提供基于Sip协议的服务,比如市话、长途电话、即时消息、语音消息、多媒体会议等。

在传统的电话呼叫场景中,供应商使用的是模拟信号,通信的两端都是电话话机,使用Sip协议之后,所有的数据都是使用数据包的形式在互联网上传输,通信的两端不再是传统的话机,而是软件电话(简称软电话)。

SIP协议交互过程

了解Sip协议交互过程之前,我们先来看看打电话的场景,假设A给B打电话,他们之间的交互一般是这样的:

  1. A给B拨号,邀请B接听电话;
  2. B的手机响铃,A同时可以听到响铃;
  3. B接听电话;
  4. A和B之间可以相互通话;
  5. B(或者A)挂断电话,通话结束;

Sip协议的交互过程和上图所示的过程基本一致,但是在协议层面还是多了两步:

  1. 在B接听电话的时候,会给A发送一个OK消息,A收到OK之后,会回复一个ACK给B,然后A和B才开始通话;
  2. 在B挂断电话的时候,会给A发送一个BYE消息,A收到BYE消息之后,会回复一个OK给B,这时整个通话才结束。

一个完整的Sip交互过程如下:

SIP协议介绍

SIP协议是一个纯文本协议,运行在应用层,底层可以使用UDP或TCP作为传输协议(默认使用UDP)。SIP协议是在HTTP和SMTP协议的基础之上发展而来,他们有很多类似的地方,比如Client/Server模式,主叫作为client发送INVITE,被叫作为Server,响应RING。

SIP协议的内容大体上可以分为四部分:开始行、消息头、空行、消息体。

  • 开始行
    格式为:Method URI SIP_VERSION
    SIP协议的Method有6种,分别是:INVITE,ACK,CANCEL,BYE,REGISTER,OPTIONS
    URI表示所请求的用户,可以理解为sip格式的被叫。被叫地址用sip来表示为sip:name@domaindomain部分可以是具体的IP,也可以是域名,默认使用的端口是5060(可以省略)。
    SIP_VERSION:SIP的版本号。

  • 消息头
    格式为name: value;key=value;一个字段一行。
    消息头一般至少会包含6个字段:Via, To, From, CSeq, Call ID, Max-Forwards

    • Via
      包含了SIP经过的所有节点信息,目的是为了让响应可以按via中的节点信息原路返回。
    • To
      sip格式的消息接收者。To后面有一个tag字段,在UAC发出建立会话请求时,由于会话还没有建立,所以此时To后面的tag字段为空,当UAS(user agent server)接收到INVITE请求,并响应1XX或2XX时,会在响应信息的To后面带上tag信息,此时结合From tag, To tag, Call id三者,就形成了本次会话的唯一ID,既dailog id。
    • From
      sip格式的消息的发送者,From后面必须要有一个tag,在UAC(user agent client)发送一个建立会话的请求时(INVITE),必须设置一个tag,此tag作为dialog ID(From tag, To tag, Call id)的一部分。
    • CSeq
      用于在同一个Dialog中标识及排序事务(transaction)以及区分新的请求 与请求的重发。
      CSeq包括顺序号和方法(method),方法必须和它所对应的request相匹配。对于out-of-dialog的非register request,取值任意。
      对于dialog内的每一个新的request(如BYE,RE-INVITE,OPTION),CSeq的序号加1。但是对于CANCEL,ACK除外。对于ACK而言,CSeq的序号必须与其所对应的request相同。对于CANCEL而言,CSeq的序号也必须与其cancel掉的request相同。
      注意:在同一个对话中的UAC和UAS分别维护自己的CSeq序号,他们发出请求的CSeq序号是不相关的
    • Call-ID
      是一个邀请(Invitation)或来自同一个UAC用户的所有登记请求(Registeration,包括更新登记,取消登记)以及由此产生的一组响应的唯一标识。比如由同一个INVITE所产生的CANCEL、ACK,他们所使用的CALL-ID都是一样的。
      一个invite可以建立多个dialog,每个dialog的Request和Response的Call-ID必须一致,唯一确定一个dialog的是dialog id(From tag, To tag, Call id三者共同确定一个dialog id)。
    • Max-Forwards
      定义了一个请求到达UAS的最大条数,这里定义的是一个整数,每经过一个节点就会自动减一,如果Max-Forwards归零还没有达到目的地,则会响应一个483的错误。
      还有几个字段不一定在消息头中存在,但是出现的频率也比较高:
    • Content-Type
      Content-Type: application/sdp
      主要表示发给接收器的消息体的媒体类型。如果消息体不是空的,则Content-type header field一定要存在。如果Content-type header field存在,而消息体是空的,表明该类型的媒体流长度是0。
    • Content-Length
      表示消息体的长度。是十进制数。
  • 空行
    用于分割消息头和消息体。

  • 消息体

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    v=0            //版本号为0
    o=user1 685988692 621323255 IN IP4 192.168.31.131 //建立者用户名+会话ID+版本+网络类型+地址类型+地址
    s=- //会话名
    c=IN IP4 192.168.31.131 //连接信息:网络类型+地址类型+地址
    t=0 0 //会话活动时间 起始时间+终止时间
    m=audio 49432 RTP/AVP 0 8 101 //媒体描述:媒体+端口+传送+格式列表 音频 + 端口49432 + 传输协议RTP + 格式AVP,有效负荷0(u率PCM编码)
    a=rtpmap:0 PCMU/8000 //0或多个会话属性: 属性 + 有效负荷+ 编码名称 + 抽样频率。 rtpmap + 0型 + PCMU + 8KHz
    a=rtpmap:8 PCMA/8000 //a 可以有多个, 见SDP协议
    a=rtpmap:101 telephone-event/8000
    a=sendrecv

INVITE消息样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 39.xxx.xxx.99:5060;branch=z9hG4bK23753624794dd277
From: <sip:[email protected]>;tag=60775f935c757d81
To: <sip:[email protected]>
Call-ID: [email protected]
CSeq: 21701 INVITE
Contact: <sip:[email protected]:5060>
Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, INFO, UPDATE, PRACK
Supported: timer, linknat
Original-Info: hiRi4hYAOwIxZGRhdxYBBGIzLTVyLEkMXgA7El4CDQAeVUpXH1ZUHwdQBgjy
Max-Forwards: 70
User-Agent: VOSxxxx V2.1.7.01
Session-Expires: 600
Content-Type: application/sdp
Content-Length: 210

v=0
o=- 39225 39225 IN IP4 183.xxx.xxx.131
s=VOS2009
c=IN IP4 183.xxx.xxx.131
t=0 0
m=audio 16782 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv

CANCEL消息样例

1
2
3
4
5
6
7
8
9
10
CANCEL sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 39.xxx.xxx.99:5060;branch=z9hG4bK0760cbc15403ab38
From: <sip:[email protected]>;tag=677c9b49690bc569
To: <sip:[email protected]>
Call-ID: [email protected]
CSeq: 21701 CANCEL
Original-Info: gXJk4BFWPQA2MmJjcEAHBmVlKzd1ek8OWVY9EFlUCdIZA0xVGABSHQAGAAoy
Max-Forwards: 70
User-Agent: VOSxxxx V2.1.7.01
Content-Length: 0

ACK消息样例

1
2
3
4
5
6
7
8
9
10
ACK sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 39.xxx.xxx.99:5060;branch=z9hG4bK33a1a5dd50ed863f
From: <sip:[email protected]>;tag=5b5abaec61e8e7a3
To: <sip:[email protected]>;tag=3373453196
Call-ID: [email protected]
CSeq: 21701 ACK
Original-Info: gXg1thFcbFY2ODM1cEpWUGVvemF1cB5YWVxsRlleWlQZCR0DGAoDSwAMUVxy
Max-Forwards: 70
User-Agent: VOSxxxx V2.1.7.01
Content-Length: 0

OK消息样例

1
2
3
4
5
6
7
SIP/2.0 200 OK
Via: SIP/2.0/UDP 111.xxx.xxx.165:1028;branch=z9hG4bK282298718;received=111.xxx.xxx.165;rport=1028
From: <sip:[email protected]>;tag=3527138319
To: <sip:[email protected]>;tag=50b1862615c60699
Call-ID: [email protected]
CSeq: 21702 BYE
Content-Length: 0

可能出现的问题

SIP协议既然可以用于通话,那么协议体中为什么没有传输音频内容?

要回答这个问题,首先还是回到本文开头部分关于SIP协议的介绍,说到底SIP协议只是一个信令控制协议,负责创建、修改、结束交互式的多媒体会话。那么语音数据的传输,还是需要配合RTP/RTCP(Realtime Transfer Protocol/Realtime Transfer ControlProtocol,实时传输协议/实时传输控制协议)协议一起使用。