SIP消息是客户机和服务器之间通信的基本信息单元,它是一个基于UTF-8的文本编码协议。SIP消息主要分为请求消息和响应消息,不管请求消息还是响应消息,它都是由一个起始行、若干个头字段和一个消息体组成,其中的消息体是可选,其格式遵循RFC2822因特网文本消息格式标准。
SIP协议结构与HTTP协议结构非常相似,其消息格式如下:
起始行
消息头部(若干个头字段)
空行
消息体(SDP)
其中的起始行对于请求消息是请求行,对于响应消息是状态行。
下图是一个sip客户端向服务端注册时的请求消息和响应消息:
请求行
请求消息的起始行为请求行。请求行的格式由方法名、请求URI和协议版本组成,各部分之间用一个空格字符进行分隔。请求行必须用回车换行字符表示行终结。请求行的格式如下:
格式:Request-Line = Method Request-URI SIP-Version
Method:方法表示请求的类型,核心的类型有6种,INVITE,ACK,BYE,CANCEL,REGISTER和OPTIONS
Request-URI:请求的URI表示此请求将要被发送的目标地址
SIP-Version:协议版本,一般为SIP/2.0
例子中的请求方法是REGISTER,Request-URI为sip:192.168.101.47:5080,SIP-Version为SIP/2.0。常见的几种请求方法的说明如下表:
状态行
响应消息的起始行为状态行,状态行由协议版本、状态码和状态原因短语组成,各个部分之间用一个空格字符进行分隔。状态行的格式如下所示:
格式: Status-Line = SIP-Version Status-Code Reason-Phrase
SIP-Version:协议版本,一般为SIP/2.0
Status-Code:状态码,该参数为一个3为的十进制整数,来报告事务的状态
Reason-Phrase:状态的原因短语
例子中协议版本为SIP/2.0,状态码为200,原因短语是OK
关于返回状态码:
1XX响应消息:呼叫进展响应,表示已经接收到请求消息,正在对其进行处理;
2XX响应消息:成功响应,表示请求已经被成功接受、处理;
3XX响应消息:重定向响应,表示需要采取进一步动作,以完成该请求;
4XX响应消息:客户端出错,表示请求消息中包含语法错误或者服务器端不能完成对该请求消息的处理,如488消息表示“此处不接受”;
5XX响应消息:服务器端出错,表示SIP服务器故障,不能完成对正确消息的处理;
6XX响应消息:全局故障,表示请求不能在任何SIP服务器上实现。
消息头部
头字段提供了关于请求(或应答)的消息和关于这些消息所包含的消息体的信息。一些头字段可以在请求或应答两种消息中使用,而其他的头字段只能单独特定地用于请求(或应答)。头字段由头字段名、后边跟着一个冒号、再后面跟着头字段值组成。头字段格式如下所示:
field-name:field-value
下面介绍常见的字段:
Via:Via头字段指定目前请求消息经过的路径,同时指定响应也要按该路径返回。该字段值中的branch ID参数是一个事务标识符,代理服务器用它来检测环路。Via头字段包含一个用来发送消息的传送协议和客户端的主机名或者网络地址,该头字段还可能包含一个接收响应的端口号。Via头字段的缩写形式为v。
Max-forwards:在RFC3261中规定,Max-Forwards(最大转发次数)头字段必须和任何方法一起规定向下游转发消息的代理服务器和网关的个数。当某客户端沿着某条链路发送请求消息的时候,使用该字段可以有效地防止链路中出错或者发生回环。Max-forwards头字段的值是一个0-255的整数,指示了该请求还允许被转发的次数。转发该请求时,每经过一个服务器该值就减一。一般默认为70。
To:该头字段指定了请求的逻辑接收者。"display-name"参数用于人机接口,为可选。"tag"参数一般用于标识对话。它的缩写形式为t。
From:From头字段用于指示请求的发起者,也就是发送请求(不是对话)的源地址。这可能与对话的发起者并不同。当被叫发出请求时,From字段中就是使用被叫的地址。From的缩写形式是f。
Call-ID:Call-ID头字段唯一地标识某个客户端的某个特定的会话或所有的注册请求。一个多媒体会议可以发起几个Call-ID不同的呼叫。Call-ID区分大小写并逐字节比较,缩写形式为i。
Cseq:命令序列头字段Cseq位于请求消息中,包含两个字段:一个无符号整数字段和一个方法名。该头字段用于把某对话中的事务进行排序且提供了一种唯一标识某事务的方法(即INVITE、ACK等method),并能够区分某请求是新的请求还是重发的请求。如果两个Cseq的数字序列以及方法都相等那么这两个Cseq就是等价的。
Contact:Contact字段的值含有一个URI,UA可根据这个地址,直接找到另一个UA,从而避开SIP服务器,当Contact头字段包含一个显示名称的时候,带有所有的URI参数的URI应放于三角括号<>中,Contact头字段的缩写是m。
Record-Route:Record-Route头字段由代理服务器插入请求消息中,这样可以使该对话中将来的请求仍能经过该代理服务器。
Route:Route头字段有一个代理服务器列表,用来指定请求消息的路由
Content-length:消息体字段长度
Server:服务器容器信息。
请求和应答都可能含有消息体,它被一个空行和消息头分开。被SIP消息携带的消息体通常是会话描述符(即SDP),它就象附件一样包含在SIP消息中。
会话描述协议(SDP,Session Description Protocol)规定了对描述会话的必要信息怎样进行编码。两个SIP实体可以通过携带SDP消息体来使它们之间的多媒体会话达成一致。
SDP用于构建INVITE和200 OK响应消息的消息体,供主/被叫用户交换媒体信息。
SDP包括以下一些方面:
会话的名称和目的
会话存活时间
包含在会话中的媒体信息,包括:
媒体类型(video, audio, etc)
传输协议(RTP/UDP/IP, H.320, etc)
媒体格式(H.261 video, MPEG video, etc)
多播或远端(单播)地址和端口
为接收媒体而需的信息(addresses, ports, formats and so on)
使用的带宽信息
可信赖的接洽信息(Contact information)
SDP会话描述是基于文字的,一个会话描述由一些类似如下形式的文字行组成:Type=value
类型域为一个单独字符,而值域的格式则取决于它前面的类型语。一个SDP描述含有会话级信息和媒体级信息,会话级信息应用于整个会话,媒体级信息作用于特殊的媒体流。一个SDP会话描述以会话级信息和媒体级信息开始,如果任意一个出现,另外一个就接着在后面出现。会话级部分以v=0开始,v代表类型,0为值,意思是协议版本号为0(SDP版本0)。接下来的行直到媒体流部分或者会话描述的终点,提供了整个会话的信息。
Java在支持SIP上发布了许多相关的规范,如Java APIs for Integrated Networks、SIP Servlet API 、JAIN SIP Lite 、SIP API for J2ME 、180),JAIN SIMPLE Presence 、Java Media Framework for RTP、JAIN SIMPLE Instant Messaging、JAIN SDP、SIP for J2ME等,而SIP Servlets规范提供了一系列的Java API和一个基于容器(Container)/应用服务器(Application Server)的开发模型,用于提高服务器端SIP应用的开发效率。
SIP Servlets同样基于Java Servlet架构,其API归属于javax.servlet.sip包和javax.servlet.http同样扩展自javax.servlet.。不同的是,HTTP Servlets通过Servlet架构实现了HTTP协议, 而SIP Servlet实现了SIP协议。一组SIP Servlets连同资源和部署描述文件打包后部署并运行在一个容器或SIP应用服务器上,容器提供了例如会话状态管理、事务管理、重发、网络连接、消息调度、线程管理、资源管理以及应用程序管理等服务。
下表是Http servlet和Sip servlet的比较:
比较项 | HTTP | SIP |
---|---|---|
Servlet Class | HttpServlet | SipServlet |
Session | HttpSession | SipSession |
Application package | war | sar |
Deployment Descriptor | web.xml | sip.xml |