SIP消息类型&&消息格式 || 拨打/应答消息代码详解
前言
1、SIP应答消息指的是由UAS或SIP服务器生成的,回应UAC请求的消息。(一个 SIP 消息既可以是一个从客户端到服务器端的请求,也可以是一个从服务器端到客户端的一个应答。)
2、应答消息可能包含UAC所需要的附加头域信息,也可能只是个简单的,用于防止UAC重发请求的确认消息。
3、有些应答消息只是UAC采取具体的额外步骤。我们将从结构的类别角度讨论应答消息。然后讨论请求相关的详细信息。
4、SIP应答消息分为六种类型。前五种是从HTTP借鉴的,而第六种是为SIP创建的。具体类别请参考后面的附表。
5、如果UAC不能理解某个特定的SIP应答码,它必须把应答按类别解释处理。比如说,UAC收到一个599 Server Unplugged应答,但不知道它的具体含义,那么,它必须按500 Server Failure处理应答消息。
6、 SIP应答消息的起始行包含应答码和原因短语,原因短语只是给人看的,SIP实现只根据应答码决定处理逻辑。因此,200 Call Failed的解释和200 OK完全一样。我们后续描述的原因短语都是RFC文档中建议的。可以用它们传递更多信息,特别是在错误响应中,短语通常会呈现给最终用户。一部分应答代码是从HTTP借鉴的,有些原因短语做了稍微的修改。然而,并不是所有HTTP应答码都对SIP有效,有时候甚至含义完全不同。
7、如果没有特别说明,我们所讨论的应答都是RFC 3261 中定义的。
8、SIP消息由一个起始行、消息头、一个标志消息头结束的空行及作为可选项的消息体组成。
或者
9、SIP消息的起始行分为请求行(Request-Line)和状态行(Status-Line)两种。其中,请求行是请求消息的起始行,状态行是响应消息的起始行。可见,请求消息包含请求行、消息头、空行和消息体;响应消息包括状态行、消息头、空行和消息体。
10、请求消息和响应消息都包括SIP消息头字段和SIP消息体字段。SIP消息头主要用来指明本消息的发起方和接受方,以及经过多少跳转等基本信息;SIP消息体主要用来描述本次会话具体实现方式;通过换行符区分命令行和每一条参数行。
SIP请求
1、SIP 请求是根据起始行中的 Request-Line 来区分的。一个 Request - Line 中包含请求方法名,Request - URI,用单个空格(SP)间隔开的协议版本。如下图所示:
2、 Request - Line 由 CRLF 结束。除了用作行结束标志以外,不允许 CR 或者 LF 出现在其他地方。在其他域中,不允许出现线形的空白(liner whitespace LWS)
Request-Line = Method SP Request-URI SP SIP-VERSION CRLF
3、Method: 这个规范规定了 6 中方法:REGISTER 用于登记联系信息,INVITE,ACK, CANCEL 用于建立会话,BYE 用于结束会话,OPTIONS 用于查询服务器负载。SIP 扩展、标准 RFC 追加可能包含扩展的方法。
4、Request-URI: Request-URI 是一个 SIP 或者 SIPS URI。也可以是一个通用的 URI(RFC 2396[5])。它标志了这个请求所用到的用户或者服务的地址。Request-URI 禁止包含空白字符或者控制字符,并且禁止用”<>”括上。也可以是一个通用的 URI(RFC 2396[5])。它标志了这个请求所用到的用户或者服务的地址。Request-URI 禁止包含空白字符或者控制字符,并且禁止用”<>”括上。
5、SIP 元素可以支持除了 SIP 或者 SIPS 之外所规定的 Request-URIs。比如”tel” URI 模式(RFC 2806[9])。SIP 元素可以用他们自己的机制来转换 non-SIP URIs 到 SIP URI,SIPS URI 或者其他什么格式的URI。
6、SIP-Version:请求和应答消息都包含当前使用的 SIP版本,这个遵循[H3.1](类似HTTP协议版本用SIP协议版本替代,用 SIP/2.0 替代 HTTP/1.1)中关于版本的规定,版本依赖,升级版本号。一个应用,发出的 SIP 消息一定包含了 SIP-Version(“SIP/2.0”)。这个 SIP 版本串是大小写不敏感的,但是在实现中必须发送大写。不像 HTTP/1.1,SIP 把版本号当作一个文本串处理。在实现上,这个应该不会有区别。
SIP应答
1、SIP 应答和 SIP 请求的区别在于请求行和状态行(响应行)的不同。状态行 = SIP协议的版本串 + Status_code + Reason-Phrase ,SIP状态行中每一个元素之间用一个单个 SP(空格)分开。
2、Status-Code 是一个 3 位的数字 result code,用来标志处理请求的一个结果。Reason-Phrase 是一个简短的 Status-Code 的说明。Status-Code 是为了能自动处理使用的,但是 Reason-Phrase 是用来给用户看得。一个客户端并不要求一定要显示或者解释这个 Reason-Phrase。建议输出这个 reason-phrase,实现中可以选择其他文本,比如用请求包头中指定的合适语言来显示。
3、status-code 的第一个数字表示了应答的类型。接下来两个数字并不作分类使用。基于这个原因,任何 status code 在 100 到 199 的可以统称位”1xx 应答”,类似的,在 200 到 299 的可以统称位”2xx 应答”,依此类推。SIP/2.0 允 许 6 类应答:
- 1xx:临时应答-请求已经接收,正在处理这个请求。
- 2xx:成功处理-请求已经成功接收,并且正确处理了这个请求。
- 3xx:重定向-还需要附加的操作才能完成这个请求,本请求转发到其他的服务器上处理。
- 4xx:客户端错误--请求包含错误的格式或者不能在这个服务器上完成。
- 5xx:服务器错误-服务器不能正确的处理这个显然合法的请求。
- 6xx:全局错误-请求不能被任何服务器处理
头域(SIP消息头)
1、SIP 头域和 HTTP 头域在语法和语义上都比较类似。任何 SIP 的包头语法都是基于如下范式的:
header = “ header-name” HCOLON header-value *(COMMA headervalue)
2、这个允许合并在具有同一个域名的多个头域,到一个用逗号分割的单个头域中。Contact 头域除了当域值是”*”之外,都允许用逗号分割的列表。
3、头域格式
每一个头域都由一个域名加上冒号(”:”)和域值组成。如下:
field-name:field-value
在消息头中,允许在冒号的左右有任意个数的空白;但是,在实现中,建议避免域名和冒号中间有空格,并且建议在冒号和值之间使用单个空格(SP)。
所以,上面的都是合法的,也是相等的,但是最后一种是我们所推荐的。头域可以扩展成为多行的,只要在每一个附加行前边用至少一个 SP 或者水平TAB(HT)打头就可以了。这种多行的头域在行结尾并且在下一行之前的空白 SP(或者 HT)将被认为是一个单个的 SP 字符。所以,下边的例子是相等的:
头域中的不同域名的相关顺序并没有什么意义。但建议与路由相关的域(VIA,ROUTE,Record-Route,Proxy-Require,MaxForwards,Proxy-Authorization 等等)放在消息头的最前边,这样可以提高处理的速度。相同域名的域之间的顺序非常重要。只有当单个头域的域值是可以用逗号分割的列表的时候,才可以表达成为同一个域名的多个头域。也就是意味着必须可以将同一个域名的多个头域在不改变消息语义的前提下,改换表达成为一对”域名: 域值”;这个转换是通过顺序增加每一个域的域值,域值之间用逗号分割。这个规则有几个例外,就是 WWWAuthenticate, Authorization, Proxy-Authenticate,和 Proxy-Authorization39头域。多个头域行可以在消息头中出现,但是由于他们的语法并不遵循上面定义的通用格式,所以,他们并不能合并成为单个头域行。
在实现上,必须能够既能够处理多个头域行的情况,也必须能够处理用逗号分割的。
合并的单个头域行的情况。下边的几组头域是相等的:
下边各组是合法的,但是并不相等:
每一个头域值的格式是依赖于它的头域名的。他可以是任意顺序的 TEXT-UTF8字符,也可以是一个空格,标记,分隔符,引号括起来的字串的组合。很多头域都回附带一个通用的域值格式。这个域值格式是由分号分开的参数名和参数值的组合:
field-name: field-value *(;parameter-name=parameter-value)
虽然在域值里边可以有任意数量的 parameter-name/parameter-value 对,但是不能允许有相同的 parameter-name 存在(唯一性)。除了特别指出的头域之外,头域中的域名、域值、parameter name parameter-value 都是大小写不敏感的。标记词始终是大小写不敏感的。除非有特别的指定,引号串的字符串是大小写敏感的。
包体
1、请求信息,包括这个规范以后的扩展的新请求,都可以包含一个消息正文体。对消息正文体的解释依赖域请求的方法(请求类型)。对于应答消息来说,请求方法和应答状态(response status code)决定了消息正文体的格式。所有的应答消息都可以有一个消息正文体(body)。
消息正文类型
消息中的 internet 媒体类别必须在 Content-Type 头域中指明。如果消息正文(body)通过某种形式的编码(encoding),比如压缩等等,都必须在Content-Encoding 头域中指明,否则 Content-Encoding 域必须忽略。如果可行,消息体的字符集作为 Content-type 头域的值的一部分表达。
在RFC2046[11]中定义的多部分”multipart” MIME类型可以在消息体中应用。在由多部分组成的消息体发送的时候,如果接受方的实现中,包头域的Accept域42中,不包含多部分的标记,那么发送方必须发送一个非多部分的session description。
SIP 消息可以包含二进制的包体或者部分包体。如果发送方没有其他显示的字符集
参数指出,媒体的文本”text”子类型会是缺省的字符集”UTF-8”。
消息体长度
在 Content-Length 头域中存放了包体的字节长度。
HTTP/1.1 的“chunked”传输编码方式并不适用于 SIP。(备注:chuncked 编码传输方式是通过把消息正文体分为一系列的块来传输的,每一块有它自己的大小标记)
分帧的SIP消息(Framing SIP Messages)
不同于 HTTP 的是,SIP 实现可以使用 UDP 或者其他非可靠传输协议。每一帧包括一个请求或者应答。
在处理以面向流的通讯为基础的 SIP 消息的时候,必须忽略在开始行之前的CRLF[H4.1]。Content-Length 头域用来确定每一个 SIP 消息在通讯流中的结束位置的。在基于面向流通讯基础上的 SIP 消息一定要使用这个头域。
SIP拨打/应答消息代码
1xx = 通知性应答
- 100 正在尝试
- 180 正在拨打
- 181 正被转接
- 182 正在排队
- 183 通话进展
2xx = 成功应答
- 200 OK
- 202 被接受:用于转介
3xx = 转接应答
- 300 多项选择
- 301 被永久迁移
- 302 被暂时迁移
- 305 使用代理服务器
- 380 替代服务
4xx = 呼叫失败
- 400 呼叫不当
- 401 未经授权:只供注册机构使用,代理服务器应使用代理服务器授权407
- 402 要求付费(预订为将来使用)
- 403 被禁止的
- 404 未发现:未发现用户
- 405 不允许的方法
- 406 不可接受
- 407 需要代理服务器授权
- 408 呼叫超时:在预定时间内无法找到用户
- 410 已消失:用户曾经存在,但已从此处消失
- 413 呼叫实体过大
- 414 呼叫URI过长
- 415 不支持的媒体类型
- 416 不支持的URI方案
- 420 不当扩展:使用了不当SIP协议扩展,服务器无法理解该扩展
- 421 需要扩展
- 423 时间间隔过短
- 480 暂时不可使用
- 481 通话/事务不存在
- 482 检测到循环
- 483 跳数过多
- 484 地址不全
- 485 模糊不清
- 486 此处太忙
- 487 呼叫被终止
- 488 此处不可接受
- 491 呼叫待批
- 493 无法解读:无法解读 S/MIME文体部分
5xx = 服务器失败
- 500 服务器内部错误
- 501 无法实施:SIP呼叫方法在此处无法实施
- 502 不当网关
- 503 服务不可使用
- 504 服务器超时
- 505 不支持该版本:服务器不支持SIP协议的这个版本
- 513 消息过长
6xx = 全局失败
- 600 各处均忙
- 603 拒绝
- 604 无处存在
- 606 不可使用
SIP消息类型
1、SIP是一个基于文本的协议,使用的是UTF-8字符集。
2、SIP消息主要分为两大类:
- 一类是由客户端发往服务器的请求消息(Request);
- 一类是由服务器发往客户端的应答消息(Response)。
3、一个基本的SIP消息包括起始行、一个或多个头字段、说明头字段结束的空行和一个可选的消息体:
消息=起始行(包括请求行/状态行;请求行规定了请求的类别,而状态行指出了每个请求的状态,比如是成功还是失败。如果是失败的话还要给出失败的原因或类型。) *头字段 CRLF [消息体] (消息首部给出了关于请求或应答的更多信息一般包括消息的来源、规定的消息接收方,另外还包括一些其他方面的重要信息。消息体通常描述将要建立会议的类型包括所交换媒体的描述,但不具体定义消息体的内容或结构,其结构或内容使用另外一个协议来描述,就是会话描述协议SDP。)
4、请求消息
请求行 = 方法 + 空格 + 请求地址 + SIP版本号 +空行(通过一个请求行作为起始行,请求行包括了方法名、请求的URL、协议版本号、中间用空格分开)
5、六种请求方法
sip消息大致被分为sip请求和sip响应 sip请求是由客户端发给服务器激活一个sip操作的消息。RFC3261定义了六种sip请求 1,INVITE--INVITE消息表明接收用户或服务器被邀请加入一个会话。也可以使用这种方式来修改先前建立会话的特性。INVITE消息体可能包含要建立或修改媒体会话的描述,使用SDP编码。INVITE的成功响应(200ok响应)表明了被叫方愿意参与会话。 2,ACK--ACK请求确认UAC(USER AGENT CLIENT)已经接收到了INVITE请求的最终响应。ACK只与INVITE一起使用。ACK用于结束一个200OK响应。前一个代理或UAC为其他最终响应发送ACK。如果INVITE请求中不含有会话描述信息,ACK可以包含一个最终会话描述的信息实体。 3,OPTIONS--UA使用OPTIONS请求向UAS(USER AGENT SERVER)查询它的功能。如果UAS可以向用户递送会话,则响应UAS的功能集。 4,BYE--UA使用BYE请求终结一个先前建立的会话。 5,CANCEL--CANCEL请求使UAC和网络服务器取消一个正在进行的请求,如INVITE。这不会影响UAC已经发送最终相应的请求。 6,REGISTER--客户端使用REGISTER请求注册它目前的位置信息。 总结: INVITE 发出呼叫会话请求 ACK INVITE请求被最终请求 BYE 释放一个呼叫会话 CANCEL 取消挂起的呼叫 REGISTER 登记注册用户代理 OPTIONS 查询服务器能力
6、应答消息
状态行 = SIP版本 + 空格 + 状态码 + 空格 + 相关文本短语 + 空行
SIP应答消息状态码与功能
类型 状态码 状态说明
临时应答(1XX)
- 100 Trying 正在处理中
- 180 Ringing 振铃
- 181 call being forwarder 呼叫正在前向
- 182 queue 排队181* session progress 会话进行
会话成功(2XX)
- 200 OK 会话成功
重定向(3XX)
- 300 multiple 多重选择
- 301 moved permanently 永久移动
- 302 moved temporaily 临时移动
- 305 use proxy 用户代理
- 380 alternative service 替代服务
请求失败(4XX)
- 400 bad request 错误请求
- 401unauthorized 未授权
- 402 payment required 付费要求
- 403 forbidden 禁止
- 404 not found 未发现
- 405 method no allowed 方法不允许
- 406 not acceptable 不可接受
- 407 proxy authentication required 代理需要认证
- 408 request timeout 请求超时
- 410 gone 离开
- 413 request entity too large 请求实体太大
- 414 request-url too long 请求URL太长
- 415 unsupported media type 不支持的媒体类型
- 416 unsupported url scheme 不支持的URL计划
- 420 bad extension 不良扩展
- 421 extension required 需要扩展
- 423 interval too brief 间隔太短
- 480 temporarily unavailable 临时失效
- 481 call/transaction does not exist 呼叫/事务不存在
- 482 loop detected 发现环路
- 483 too many hops 跳数太多
- 484 address incomplete 地址不完整
- 485 ambiguous 不明朗
- 486 busy here 这里忙
- 487 request terminated 请求终止
- 488 not acceptable here 这里请求不可接受
- 491 request pending 未决请求
- 493 undecipherable 不可辨识
服务器失败(5XX)
- 500 server inte
- 501 not implemented 不可执行
- 502 bad gateway 坏网关
- 503 service unavailable 服务无效
- 504 server time-out 服务器超时505 version not supported 版本不支持
- 513 message too large 消息太大
全局性错误(6XX)
- 600 busy everywhere 全忙
- 603 decline 丢弃
- 604 does not exist anywhere 不存在
- 606 not acceptable 不可接受
SIP应答代码
应答码是包含并且扩展了HTTP/1.1协议版本的应答码。当然并不是所有的HTTP/1.1应答码都适当应用,只有在这里指出的是适当的。其他的HTTP/1.1协议版本的应答码不应当使用。并且,SIP消息类型也定义了新的应答码系列:6xx。
1 临时应答1xx
临时应答,也就是消息性质的应答,标志了对方服务器正在处理请求,并且还没有决定最后的应答。如果服务器处理请求需要花200ms以上才能产生终结应答的时候,它应当发送一个1xx应答。
注意:1xx应答并不是可靠传输的。他们不会导致客户端传送一个ACK应答。临时性质的(1xx)应答可以包含消息体,包含会话描述。
1.1、100 Trying
这个应答表示下一个节点的服务器已经接收到了这个请求并且还没有执行这个请求的特定动作(比如,正在打开数据库的时候)。这个应答,就像其他临时应答一样,种植了UAC重新传送INVITE请求。100(Trying)应答和其他临时应答不同的是,在这里,它永远不会被有状态proxy转发到上行流中。
1.2、180 Ringing
UA收到INVITE请求并且试图提示给用户。这个应答应当初始化一个本地回铃。
1.3、818 Call is Being Forwarded(呼叫被转发)
服务器可以用这个应答代码来表示呼叫正在转发到另一个目的地集合。
1.4、182 Queued
当呼叫的对方暂时不能接收呼叫的时候,并且服务器决定将呼叫排队等候,而不是拒绝呼叫的时候,那么就应当发出这个应答。当被叫方一旦恢复接收呼叫,他会返回合适的终结应答。对于这个呼叫状态,可以有一个表示原因的短语,比如:”5 calls queued;expected waiting timeis 15minutes”。服务器可以给出好几个182(Queued)应答告诉呼叫方排队的情况(比如排队靠前了等等)。
1.5、183 会话进度
183(Session Progress)应答用于提示建立对话的进度信息。Reason-Phrase(表达原因的句子)、头域或者消息体可以用于提示呼叫进度的更消息的信息。
2、成功信息2xx
这个应答表示请求是成功的。
2.1、200 OK
请求已经处理成功。这个信息取决于不同方法的请求的应答。
3、转发请求3XX
3xx系列的应答是用于提示用户的新位置信息的,或者为了满足呼叫而转发的额外服务地点。
3.1、300 Multiple Choices
请求的地址有多个选择,每个选择都有自己的地址,用户或者(UA)可以选择合适的通讯终端,并且转发这个请求到这个地址。应答可以包含一个具有每一个地点的在Accept请求头域中允许的资源特性,这样用户或者UA可以选择一个最合适的地址来转发请求。没有未这个应答的消息体定义MIME类型。这些地址选择也应当在Contact头域中列出(20.10节)。不同于HTTP,SIP应答可以包含多个Contact头域或者一个Contact头域中具有一个地址列表。UA可以使用Contact头域来自动转发或者要求用户确认转发。不过,本规范没有定义自动转发的标准。如果被叫方可以在多个地址被找到,并且服务器不能或者不愿意转发请求的时候,可以使用这个应答来给呼叫方。
3.2、301 Moved Permently
请求的地址有多个选择,每个选择都有自己的地址,用户或者(UA)可以选择合适的通讯终端,并且转发这个请求到这个地址。应答可以包含一个具有每一个地点的在Accept请求头域中允许的资源特性,这样用户或者UA可以选择一个最合适的地址来转发请求。没有未这个应答的消息体定义MIME类型。这些地址选择也应当在Contact头域中列出(20.10节)。不同于HTTP,SIP应答可以包含多个Contact头域或者一个Contact头域中具有一个地址列表。UA可以使用Contact头域来自动转发或者要求用户确认转发。不过,本规范没有定义自动转发的标准。如果被叫方可以在多个地址被找到,并且服务器不能或者不愿意转发请求的时候,可以使用这个应答来给呼叫方。
3.2、301 Moved Permently
当不能在Request-URI指定的地址找到用户的时候,请求的客户端应当使用Contact头域(20.10)所指出的新的地址重新尝试。请求者应当用这个新的值来更新本地的目录,地址本,和用户地址cache,并且在后续请求中,发送到这个/这些列出的地址。
3.3、302 Moved Temporarily
请求方应当把请求重新发到这个Contact头域所指出的新地址(20.10)。新请求的Request-URI应当用这个应答的Contact头域所指出的值。在应答中的Expires(20.19节)或者Contact头域的expires参数定义了这个Contact URI的生存周期。UA或者proxy在这个生存周期内cache这个URI。如果没有严格的有效时见,那么这个地址仅仅本次有效,并且不能在以后的事务中保存。如果cache的Contact头域的值失败了,那么被转发请求的Request-URI应当再次尝试一次。临时URI可以比超时时间更快的失效,并且可以有一个新的临时URI。
3.4、305 Use Proxy
请求的资源必须通过Contact头域中指出的proxy来访问。Contact头域指定了一个proxy的URI。接收到这个应答的对象应当通过这个proxy重新发送这个单个请求。305(UseProxy)必须是UAS产生的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2021-05-11 支付功能如何测试
2021-05-11 接口基础知识