SIP协议格式解读
SIP协议包括三个部分:起始⾏、⼀个/多个字段(field)组成的消息头、⼀个标志消息头结束的空⾏(CRLF)以及作为可选项的消息体(message body)组成。
1. 起始⾏
起始⾏分请求的起始⾏和响应的起始⾏
1.1 请求起始⾏
⼀个 Request_line 包含⽅法名字, Request-URI,⽤单个空格(SP)间隔开的协议版本。 Request-Line 由 CRLF 结束。除了⽤作⾏结束标志以外,不允许 CR 或者 LF 出现在其他地⽅。
格式:
Request-Line = Method SP Request-URI SP SIP-VERSION CRLF
举例:REGISTER sip: SIP2.0
具体含义:
名称含义
Method 规定了 6 中⽅法:REGISTER ⽤于登记联系信息,INVITE, ACK,CANCEL ⽤于建⽴会话,BYE ⽤于结束会话,OPTIONS ⽤于查询服务
器负载。 SIP 扩展、标准 RFC 追加可能包含扩展的⽅法。
SIP 元素可以⽀持除了 SIP 或者 SIPS 之外所规定的 Request-URIs。⽐如”tel” URI 模式(RFC 2806[9])。SIP 元素可以⽤他们⾃⼰的机制来转换 non-SIP URIs 到 SIP URI, SIPS URI 或者其他什么格式的 URI
Request-
URI 是⼀个 SIP 或者 SIPS URI,也可以是⼀个通⽤的 URI(RFC 2396[5])。它标志了这个请求所⽤到的⽤户或者服务的地址。 Request-URI 禁
⽌包含空⽩字符或者控制字符,并且禁⽌⽤”<>”括上
SIP-Version 请求和应答消息都包含当前使⽤的 SIP 版本,这个遵循[H3.1](类似 HTTP⽤ SIP 替代,⽤ SIP/2.0 替代 HTTP/1.1)中关于版本的规定,版本依赖,升级版本号。⼀个应⽤,发出的 SIP 消息⼀定包含了 SIP-Version “SIP/2.0”。这个 SIP 版本串是⼤⼩写不铭感的,但是在实现中必
菜叶简笔画须发送⼤写。
// SIP请求消息的起始⾏(RFC3261-7.1)
type RequestLine struct{
Method string // 请求⽅法
RequestURI URI // SIP消息⽬标地址,⽆"<>"尖括号
SIPVersion string // SIP版本号
}
1.2 响应起始⾏
SIP 应答和 SIP 请求的区别在于在 START-LINE 中是否包含⼀个 STATUS-LINE。⼀个status-line 在由数字表达的 status-code 之前,是⼀个协议的版本串,每⼀个元素之间⽤⼀个单个 SP(空格)分开。 除了最后⽤作结束标志以外,CR/LF 不允许出现在其他地⽅。格式:
status-line = SIP-VERSION SP STATUS-CODE SP Reasong-Phra CRLF
举例:SIP/2.0 200 OK
具体含义:
名称含义
SIP-Version 请求和应答消息都包含当前使⽤的 SIP 版本,这个遵循[H3.1](类似 HTTP⽤ SIP 替代,⽤ SIP/2.0 替代 HTTP/1.1)中关于版本的规定,版本依赖,升级版本号。⼀个应⽤,发出的 SIP 消息⼀定包含了 SIP-Version “SIP/2.0”。这个 SIP 版本串是⼤⼩写不铭感的,但是在实现中必
须发送⼤写。
Status-
Code
⼀个 3 位的数字 result code,⽤来标志处理请求的⼀个结果。
Reason-Phra 是⼀个简短的 Status-Code 的说明。Status-Code 是为了能⾃动处理使⽤的,但是 Reason-Phra 是⽤来给⽤户看得。⼀个客户端并不要
求⼀定要显⽰或者解释这个 Reason-Phra。
其中,status-code 的第⼀个数字表⽰了应答的类型。接下来两个数字并不作分类使⽤。基于这个原因,任何 status code 在 100 到199 的可以统称位”1xx 应答”,类似的,在 200到 299 的可以统称位”2xx 应答”,依此类推。SIP/2.0 允许 6 类应答:
1xx:临时应答-请求已经接收,正在处理这个请求。
2xx:成功处理-请求已经成功接收,并且正确处理了这个请求。
3xx:重定向-还需要附加的操作才能完成这个请求,本请求转发到其他的服务器上处理。
4xx:客户端错误--请求包含错误的格式或者不能在这个服务器上完成。
5xx:服务器错误-服务器不能正确的处理这个显然合法的请求。
6xx:全局错误-请求不能被任何服务器处理。
// SIP应答消息的起始⾏(RFC3261-7.2)
洗手歌type ResponLine struct{
SIPVersion string // SIP版本号
StatusCode int// 状态码
ReasonPhra string // 状态码的说明屈平疾王听之不聪也
}
```cpp
package sip
const(
// SIP版本号
SIPVersion ="SIP/2.0"
// 协议类型
SchemeSip ="sip"
/
/ SIP请求⽅法-RFC3261
MethodInvite ="INVITE"
MethodAck ="ACK"
考试后的感想作文MethodBye ="BYE"
MethodCancel ="CANCEL"
MethodOptions ="OPTIONS"
MethodRegister ="REGISTER"
// SIP请求⽅法-其他协议
MethodPrack ="PRACK"// [RFC3262]
MethodSubscribe ="SUBSCRIBE"// [RFC6665]
MethodNotify ="NOTIFY"// [RFC6665]
MethodPublish ="PUBLISH"// [RFC3903]
佛山市三水区MethodInfo ="INFO"// [RFC6086]
MethodRefer ="REFER"// [RFC3515]
MethodMessage ="MESSAGE"// [RFC3428]
MethodUpdate ="UPDATE"// [RFC3311]
MethodPing ="PING"// [tools.ietf/html/draft-fwmiller-ping-03]
)
**2. SIP 头域**
SIP 的包头语法都是基于如下范式的:
*header = “ header-name” HCOLON header-value *(COMMA header-value)* *
这个允许合并在具有同⼀个域名的多个头域,到⼀个⽤逗号分割的单个头域中。Contact头域除了当域值是”*”之外,都允许⽤逗号分割的列表。
每⼀个头域都由⼀个域名加上冒号(”:”)和域值组成。
*field-name:field-value*
在消息头中,允许在冒号的左右有任意个数的空⽩;但是,在实现中,建议避免域名和冒号中间有空格,并且建议在冒号和值之间使⽤单个空格(SP)。
每⼀个头域值的格式是依赖于它的头域名的。他可以是任意顺序的 TEXT-UTF8 字符,也可以是⼀个空格,标记,分隔符,引号括起来的字串的组合。很多头域都回附带⼀个通⽤的域值格式。这个域值格式是由分号分开的参数名和参数值的组合:
*field-name: field-value *(;parameter-name=parameter-value)*
虽然在域值⾥边可以有任意数量的 parameter-name/parameter-value 对,但是不能允许有相同的 parameter-name 存在(唯⼀性)。除了特别指出的头域之外,头域中的域名、域值、parameter name parameter-value 都是⼤⼩写不敏感的。标记词始终是⼤⼩写不铭感的。除⾮有特别的指定,引号串的字符串是⼤⼩写敏感的。例如:
***Contact: <sip:>;expires=3600***
```cpp
// SIP头域(RFC3261-7.3)
// ⾏范式:header = "header-name" HCOLON header-value *(COMMA header-value)
// 头域⾄少包含TO、FROM、CSeq、Call-ID、Max-Forwards、Via字段
type Header struct {
Via ViaList // (RFC3261-8.1.1.7) 请求路径
From Ur // (RFC3261-8.1.1.3) 请求的原始发起者
To Ur // (RFC3261-8.1.1.2) 请求的原始到达者
CallID string // (RFC3261-8.1.1.4) 唯⼀标志
CSeq CSeq // (RFC3261-8.1.1.5) 命令序列号
MaxForwards MaxForwards // (RFC3261-8.1.1.6) 最⼤转发数量限制
ContentLength int // 正⽂长度
ContentType string // (可选) 正⽂格式描述
Contact *Ur // (可选) (RFC3261-8.1.1.8) 直接访问⽅式
Expires Expires // (可选) 消息或内容过期时间
Route Route // (可选) 请求的路由表
RecordRoute RecordRoute // (可选) 后续消息流处理的服务器列表
UrAgent string // (可选) UAC的信息
Authorization string // (可选) ⽤户认证信息
WWWAuthenticate string // (可选) ⽀持的认证⽅式和适⽤realm的参数的拒绝原因
UnsupportLines []string // 暂不⽀持的⾏
}
3. SIP包体车打蜡
请求信息,包括这个规范以后的扩展的新请求,都可以包含⼀个消息正⽂体。对消息正⽂体的解释依赖域请求的⽅法(请求类型)。对于应答消息来说,请求⽅法和应答状态(respon status code)决定了消息正⽂体的格式。所有的应答消息都可以有⼀个消息正⽂体(body)。
消息中的 internet 媒体类别必须在 Content-Type 头域中指明。如果消息正⽂(body)通过某种形式的编码(encoding),⽐如压缩等等,都必须在 Content-Encoding 头域中指明,否则 Content-Encoding 域必须忽略。如果可⾏,消息体的字符集作为 Content-type头域的值的⼀部分表达。
在 RFC2046[11]中定义的多部分”multipart” MIME 类型可以在消息体中应⽤。在由多部分组成的消息体发送的时候,如果接受⽅的实现中,包头域的 Accept 域中,不包含多部分的标记,那么发送⽅必须发送⼀个⾮多部分的 ssion description。1
SIP 消息可以包含⼆进制的包体或者部分包体。如果发送⽅没有其他显⽰的字符集参数指出,媒体的⽂本”text”⼦类型会是缺省的字符集”UTF-8”。
// SIP返回状态码信息
type StatusCodeItem struct{
Code int
Reason string
}
// SIP返回状态码
var (
// 1xx - 临时应答
StatusTrying = StatusCodeItem{100,"Trying"}
StatusRinging = StatusCodeItem{180,"Ringing"}
StatusCallIsBeingForwarded = StatusCodeItem{181,"Call Is Being Forwarded"}
StatusQueued = StatusCodeItem{182,"Queued"}
StatusSessionProgress = StatusCodeItem{183,"Session Progress"}
StatusSessionProgress = StatusCodeItem{183,"Session Progress"}
/
/ 2xx - 成功处理
StatusOK = StatusCodeItem{200,"OK"}
// 3xx - 重定向
StatusMultipleChoices = StatusCodeItem{300,"Multiple Choices"}
StatusMovedPermanently = StatusCodeItem{301,"Moved Permanently"}
StatusMovedTemporarily = StatusCodeItem{302,"Moved Temporarily"}
StatusUProxy = StatusCodeItem{305,"U Proxy"}
StatusAlternativeService = StatusCodeItem{380,"Alternative Service"}
// 4xx - 客户端错误
StatusBadRequest = StatusCodeItem{400,"Bad Request"}
StatusUnauthorized = StatusCodeItem{401,"Unauthorized"}
StatusPaymentRequired = StatusCodeItem{402,"Payment Required"}
StatusForbidden = StatusCodeItem{403,"Forbidden"}
StatusNotFound = StatusCodeItem{404,"Not Found"}
StatusMethodNotAllowed = StatusCodeItem{405,"Method Not Allowed"}
StatusNotAcceptable = StatusCodeItem{406,"Not Acceptable"}
StatusProxyAuthenticationRequired = StatusCodeItem{407,"Proxy Authentication Required"} StatusRequestTimeout = StatusCodeItem{408,"Request Timeout"}
StatusGone = StatusCodeItem{410,"Gone"}
StatusRequestEntityTooLarge = StatusCodeItem{413,"Request Entity Too Large"}
StatusRequestURITooLong = StatusCodeItem{414,"Request-URI Too Long"}
StatusUnsupportedMediaType = StatusCodeItem{415,"Unsupported Media Type"}苹果手机怎么格式化
StatusUnsupportedURIScheme = StatusCodeItem{416,"Unsupported URI Scheme"}
StatusBadExtension = StatusCodeItem{420,"Bad Extension"}
StatusExtensionRequired = StatusCodeItem{421,"Extension Required"}
StatusIntervalTooBrief = StatusCodeItem{423,"Interval Too Brief"}
StatusNoRespon = StatusCodeItem{480,"No Respon"}
StatusCallTransactionDoesNotExist = StatusCodeItem{481,"Call/Transaction Does Not Exist"} StatusLoopDetected = StatusCodeItem{482,"Loop Detected"}
StatusTooManyHops = StatusCodeItem{483,"Too Many Hops"}
StatusAddressIncomplete = StatusCodeItem{484,"Address Incomplete"}
StatusAmbigious = StatusCodeItem{485,"Ambiguous"}
StatusBusyHere = StatusCodeItem{486,"Busy Here"}
StatusRequestTerminated = StatusCodeItem{487,"Request Terminated"}
StatusNotAcceptableHere = StatusCodeItem{488,"Not Acceptable Here"}
StatusRequestPending = StatusCodeItem{491,"Request Pending"}
StatusUndecipherable = StatusCodeItem{493,"Undecipherable"}
// 5xx - 服务器错误
StatusServerInternalError = StatusCodeItem{500,"Server Internal Error"}
StatusNotImplemented = StatusCodeItem{501,"Not Implemented"}
StatusBadGateway = StatusCodeItem{502,"Bad Gateway"}
StatusServiceUnavailable = StatusCodeItem{503,"Service Unavailable"}
StatusServerTimeout = StatusCodeItem{504,"Server Timeout"}
成考英语作文范文
StatusVersionNotSupported = StatusCodeItem{505,"Version Not Supported"}
StatusMessageTooLarge = StatusCodeItem{513,"Message Too Large"}
// 6xx - 全局错误
StatusBusyEverywhere = StatusCodeItem{600,"Busy Everywhere"}
StatusDecline = StatusCodeItem{603,"Decline"}
StatusDoesNotExistAnywhere = StatusCodeItem{604,"Does Not Exist Anywhere"}
StatusUnacceptable = StatusCodeItem{606,"Not Acceptable"}
)