SIP协议简介
Sip协议的全称是会话初始协议(Session Initiation Protocol),用于控制发起、修改、终结交互式多媒体会话的信令协议。在现在的通信领域,越来越多的电信供应商都在提供基于Sip协议的服务,比如市话、长途电话、即时消息、语音消息、多媒体会议等。
在传统的电话呼叫场景中,供应商使用的是模拟信号,通信的两端都是电话话机,使用Sip协议之后,所有的数据都是使用数据包的形式在互联网上传输,通信的两端不再是传统的话机,而是软件电话(简称软电话)。
SIP协议交互过程
了解Sip协议交互过程之前,我们先来看看打电话的场景,假设A给B打电话,他们之间的交互一般是这样的:
- A给B拨号,邀请B接听电话;
- B的手机响铃,A同时可以听到响铃;
- B接听电话;
- A和B之间可以相互通话;
- B(或者A)挂断电话,通话结束;
Sip协议的交互过程和上图所示的过程基本一致,但是在协议层面还是多了两步:
- 在B接听电话的时候,会给A发送一个
OK
消息,A收到OK
之后,会回复一个ACK
给B,然后A和B才开始通话; - 在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@domain
,domain
部分可以是具体的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
表示消息体的长度。是十进制数。
- Via
空行
用于分割消息头和消息体。消息体
1
2
3
4
5
6
7
8
9
10v=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 | INVITE sip:[email protected] SIP/2.0 |
CANCEL消息样例
1 | CANCEL sip:[email protected] SIP/2.0 |
ACK消息样例
1 | ACK sip:[email protected] SIP/2.0 |
OK消息样例
1 | SIP/2.0 200 OK |
可能出现的问题
SIP协议既然可以用于通话,那么协议体中为什么没有传输音频内容?
要回答这个问题,首先还是回到本文开头部分关于SIP协议的介绍,说到底SIP协议只是一个信令控制协议,负责创建、修改、结束交互式的多媒体会话。那么语音数据的传输,还是需要配合RTP/RTCP(Realtime Transfer Protocol/Realtime Transfer ControlProtocol,实时传输协议/实时传输控制协议)协议一起使用。