您的位置:首页 > 其它

SIP 消息简介

2007-03-24 20:11 288 查看
 

1. SIP消息格式:
SIP协议是一个基于文本的协议,使用UTF-8字符集(RFC2279[7])。
一个SIP消息既可以是一个从客户端到服务器端的请求,也可以是一个从服务器端到客户端的一个应答。
这两种消息类型都由一个起始行,一个或者多个消息头,一个可选的消息正文组成。
 
消息=            起始行
                        *消息头
                        CRLF(空行,不可缺少)
                       [消息正文]
其中,起始行= 请求行 / 状态行
 
起始行、每一个消息头行,空行、都必须由回车换行组成(CRLF)。即使没有消息正文,也必须有一个空行。
除了在字符集上的区别以外,很多SIP的消息和包头域的格式都同HTTP/1.1一样。
2. 请求
SIP请求是根据起始行中的Request-Line来区分的。一个Request_line包含方法名字,Request-URI,用单个空格(SP)间隔开的协议版本。
Request-Line由CRLF结束。除了用作行结束标志以外,不允许CR或者LF出现在其他地方。在其他域中,不允许出现线形的空白(liner whitespace LWS)
 
Request-Line =     Method SP Request-URI SP SIP-VERSION CRLF
Method: 这个规范规定了6中方法:REGISTER用于登记联系信息,INVITE,ACK,CANCEL用于建立会话,BYE用于结束会话,OPTIONS用于查询服务器负载。SIP扩展、标准RFC追加可能包含扩展的方法。
Request-URI: Request-URI是一个SIP或者SIPS URI,他们在19.1节由描述。也可以是一个通用的URI(RFC 2396[5])。它标志了这个请求所用到的用户或者服务的地址。Request-URI禁止包含空白字符或者控制字符,并且禁止用”<>”括上。
SIP 元素可以支持除了SIP或者SIPS之外所规定的Request-URIs。比如”tel” URI模式(RFC 2806[9])。SIP元素可以用他们自己的机制来转换non-SIP URIs到SIP URI,SIPS URI或者其他什么格式的URI。(这一段不够清楚,详细参阅协议)
SIP-Version请求和应答消息都包含当前使用的SIP版本,这个遵循[H3.1](类似HTTP用SIP替代,用SIP/2.0替代HTTP/1.1)中关于版本的规定,版本依赖,升级版本号。一个应用,发出的SIP消息一定包含了SIP-Version “SIP/2.0”。这个SIP版本串是大小写不铭感的,但是在实现中必须发送大写。
不像HTTP/1.1,SIP把版本号当作一个文本串处理。在实现上,这个应该不会有区别。
3. 应答
SIP应答和SIP请求的区别在于在START-LINE中是否包含一个STATUS-LINE。一个status-line在由数字表达的status-code之前,是一个协议的版本串,每一个元素之间用一个单个SP(空格)分开。
除了最后用作结束标志以外,CR/LF不允许出现在其他地方。
status-line      = SIP-VERSION SP STATUS-CODE SP Reasong-Phrase CRLF
Status-Code 是一个3位的数字result code,用来标志处理请求的一个结果。Reason-Phrase是一个简短的Status-Code的说明。Status-Code是为了能自动处理使用的,但是Reason-Phrase是用来给用户看得。一个客户端并不要求一定要显示或者解释这个Reason-Phrase。本文档建议输出这个reason-phrase,实现中可以选择其他文本,比如用请求包头中指定的合适语言来显示。
status-code的第一个数字表示了应答的类型。接下来两个数字并不作分类使用。基于这个原因,任何status code在100到199的可以统称位”1xx应答”,类似的,在200到299的可以统称位”2xx应答”,依此类推。SIP/2.0允许6类应答:
1xx:临时应答-请求已经接收,正在处理这个请求。
2xx:成功处理-请求已经成功接收,并且正确处理了这个请求。
3xx:重定向-还需要附加的操作才能完成这个请求,本请求转发到其他的服务器上处理。
4xx:客户端错误--请求包含错误的格式或者不能在这个服务器上完成。
5xx:服务器错误-服务器不能正确的处理这个显然合法的请求。
6xx:全局错误-请求不能被任何服务器处理。
21节定义了详细的代码说明。
4. 消息头域
SIP头域和HTTP头域在语法和语义上都比较类似。特别的,SIP头域遵循[H4.2]关于消息头的语法的定义,并且遵循多行的扩展头域的规则。(后者 is specified in HTTP with implicit whitespace and folding)。这个规范遵循RFC2234[10],并且把清晰的空白和封装作为内在的语法规则。
[H4.2]也定义了具有相同域名的多个头域,他们的值是用逗号分开的列表,可以合并到一个头域中。这个也适用于SIP,但是细节上略有不同,因为语法不同。实际上,任何SIP的包头语法都是基于如下范式的:
header = “ header-name” HCOLON header-value *(COMMA header-value)
这个允许合并在具有同一个域名的多个头域,到一个用逗号分割的单个头域中。Contact头域除了当域值是"*"之外,都允许用逗号分割的列表。
 
4.1 头域格式
     头域遵循在RFC2822的2.2节定义的通用头域格式。每一个头域都由一个域名加上冒号(”:”)和域值组成。
              field-name:field-value
消息头的正则语法在25节中有介绍介绍。
在消息头中,允许在冒号的左右有任意个数的空白;但是,在实现中,建议避免域名和冒号中间有空格,并且建议在冒号和值之间使用单个空格(SP)。
              Subject:         lunch
              Subject    :     lunch
              Subject         :lunch
              Subject: lunch
所以,上面的都是合法的,也是相等的,但是最后一种是我们所推荐的。
头域可以扩展成为多行的,只要在每一个附加行前边用至少一个SP或者水平TAB(HT)打头就可以了。这种多行的头域在行结尾并且在下一行之前的空白SP(或者HT)将被认为是一个单个的SP字符。所以,下边的例子是相等的:
            Subject: I know you’re there, pick up the phone and talk to me!
Subject: I know you’re there,
                     pick up the phone,
                     and talk to me!
头域中的不同域名的相关顺序并没有什么意义。虽然如此,我们还是强烈建议与路由相关的域(VIA,ROUTE,Record-Route,Proxy-Require,Max-Forwards,Proxy-Authorization等等)放在消息头的最前边,这样可以提高处理的速度。相同域名的域之间的顺序非常重要。只有当单个头域的域值是可以用逗号分割的列表的时候,才可以表达成为同一个域名的多个头域(这就是说,如果遵循7.3定义的语法)。也就是意味着必须可以将同一个域名的多个头域在不改变消息语义的前提下,改换表达成为一对”域名: 域值”;这个转换是通过顺序增加每一个域的域值,域值之间用逗号分割。这个规则有几个例外,就是WWW-Authenticate,Authorization,Proxy-Authenticate,和Proxy-Authorization头域。多个头域行可以在消息头中出现,但是由于他们的语法并不遵循7.3中定义的通用格式,所以,他们并不能合并成为单个头域行。
在实现上,必须能够既能够处理多个头域行的情况,也必须能够处理用逗号分割的合并的单个头域行的情况。
下边的几组头域是相等的:
       Route: <sip:alice@atlanta.com>
       Subject: Lunch
       Route: <sip:bob@biloxi.com>
       Route: <sip:carol@chicago.com>
      
Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>
       Route: <sip:carol@chicago.com>
       Subject: Lunch
 
       Subject: Lunch
       Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>
                     <sip:carol@chicago.com>
 
下边各组是合法的,但是并不相等。
Route: <sip:alice@atlanta.com>
Route: <sip:bob@biloxi.com>
Route: <sip:carol@chicago.com>
 
Route: <sip:bob@biloxi.com>
Route: <sip:alice@atlanta.com>
Route: <sip:carol@chicago.com>
 
Route: <sip:alice@atlanta.com>,<sip:carol@chicago.com>,<sip:bob@biloxi.com>
 
每一个头域值的格式是依赖于它的头域名的。他可以是任意顺序的TEXT-UTF8字符,也可以是一个空格,标记,分隔符,引号括起来的字串的组合。很多头域都回附带一个通用的域值格式。这个域值格式是由分号分开的参数名和参数值的组合:
       field-name: field-value *(;parameter-name=parameter-value)
虽然在域值里边可以有任意数量的parameter-name/parameter-value对,但是不能允许有相同的parameter-name存在(唯一性)。除了特别指出的头域之外,头域中的域名、域值、parameter name parameter-value都是大小写不敏感的。标记词始终是大小写不铭感的。除非有特别的指定,引号串的字符串是大小写敏感的。例如:
       Contact: <sip:alice@atlanta.com>;expires=3600

       CONTACT: <sip:alice@atlanta.com>; ExPiReS=3600
相同。
       Content-Disposition: session;handling=optional

       content-disposition: Session;HANDLING=OPTIONAL
相同。
下边的两个头域不相同:
       Warning: 370 devnull “Choose a bigger pipe”
       Warning: 370 devnull “CHOOSE A BIGGER PIPE”
 
4.2 消息头域分类
     有一些消息头域是仅仅在请求(或者应答)中有效的。这些消息头域叫做请求头域或者应答头域。如果消息中的头域与这个消息的类型不匹配(比如在应答消息中出现的请求头域),这个头域必须被忽略。20节定义了每一个头域的    分类。
4.3 缩写格式
SIP提供了一个用缩写格式来表达通用头域名字的机制。这个有助于避免消息过大而导致通讯层无法传输(比如在UDP传输的时候超过了最大传输单元(MTU))。这个缩写格式在20节定义。
缩写格式的消息头域名字可以在不改变消息语义的情况下替代较大的消息头域名字。在单个消息中,头域名字既可以用长的格式,也可以用缩写格式。在实现中,必须同时支持对长名字和缩写名字的处理。
5 正文
请求信息,包括这个规范以后的扩展的新请求,都可以包含一个消息正文体。对消息正文体的解释依赖于请求的方法类型。
对于应答消息来说,请求方法类型和应答状态(response status code)决定了消息正文体的解释。所有的应答消息都可以有一个消息正文体(body)。
51 消息正文类型(Message Body Type)
消息中的internet媒体类别必须在Content-Type头域中指明。如果消息正文(body)通过某种形式的编码(encoding),比如压缩等等,都必须在Content-Encoding 头域中指明,否则Content-Encoding域必须被忽略。如果可行,消息体的字符集作为Content-type头域的值的一部分表达。
 
在RFC2046[11]中定义的多部分(“multipart”) MIME类型可以在消息体中应用。在由多部分组成的消息体发送的时候,如果接受方的实现中,包头域的Accept域中,不包含多部分的标记,那么发送方必须发送一个非多部分的session description。
SIP消息可以包含二进制的正文或者部分正文。如果发送方没有提出其他显式的字符集参数,媒体的文本类型的缺省字符集式“UTF-8”。
5.2 消息体长度
在Content-Length消息头域中存放了消息体的字节长度。第20.14节讲述了本域的详细解释。
HTTP/1.1的“chunked”传输编码方式并不适用于SIP。(备注:chuncked编码传输方式是通过把消息正文体分为一系列的块来传输的,每一块有它自己的大小标记)
 
6 分帧的SIP消息(Framing SIP Messages)
不同于HTTP的是,SIP实现可以使用UDP或者其他非可靠传输协议。每一帧包括一个请求或者应答。第18节讲述了非可靠传输的应用。
在处理以流的方式传输的SIP消息的时候,必须忽略在开始行(start line)之前的CRLF[H4.1]。
Content-Length消息头域是用来确定每一个SIP消息在通讯流中的结束位置的。在以流的方式传输的SIP消息中一定要使用这个头域。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息