SIP协议解析与实现(c和c++使用osip)1

SIP协议解析与实现(c和c++使⽤osip)1
本⽂将按照RFC3261逐步的介绍SIP协议,介绍了c和c++语⾔的实现,分析了osip库的使⽤和实现。
第⼀章概述
⼀概述
SIP协议是⼀个基于应⽤层的会话控制协议。它可以创建、修改、终⽌多媒体会话(会议),也可以邀请参与者加⼊到⼀个现有的会话。
因为SIP是⼀个基于应⽤层的协议,所以它不是⼀套完整的通讯系统⽅案,它需要和其它的⽅案或者协议结合起来实现整套系统。例如,实时传输协议(RTP)(RFC1889)⽤来传输⾳视频等实时的流媒体数据。实时流协议(RTSP)(RFC2326)⽤来控制媒体流的传递。媒体⽹关控制协议(MEGACO)(RFC3015)⽤来控制PSTN⽹关。uv喷涂工艺
由此可见,SIP协议应该⽤来组合其它协议,从⽽实现完整的服务。但是,SIP基础的功能和操作不依赖于其它协议。
⼆第⼀个例⼦
图1
下⾯引⽤RFC3261的例⼦来说明sip的基本功能,包括:定位终端,发送通讯请求,协商会话参数,建⽴会话和撤销建⽴的会话。图1显⽰了⽤户Alice和Bob使⽤SIP交换信息的⼀个典型的例⼦(每⼀个消息⽤字母F和⼀个数字来标号,标号的前⾯有⼀个简短的消息类型说明)。在这个例⼦中,Alice使⽤⼀个在她的PC机中的SIP应⽤程序呼叫Bob,Bob使⽤他的SIP电话,这个SIP电话登录了互联⽹。同时,请注意两个SIP代理服务器在Alice和Bob的会话的建⽴中起到的作⽤。
Alice呼叫Bob是使⽤他的SIP标识符。SIP标识符是⼀种URI(Uniform Resource Identifier),称之为SIP URI。SIP URI格式很象email地址,包含⼀个⽤户名和⼀个主机名,如:sip:。这⾥biloxi是Bob的
SIP服务提供者的域名。Alice的SIP URI是:sip:。SIP也⽀持安
节能灯灯头全URI,叫做SIPS URI,例如,sips:。⼀个向SIPS URI的呼叫使⽤加密传输(也就是TLS)来携带从呼叫者到被呼叫者所有的SIP消息。
SIP是⼀个与HTTP协议很像的,请求/应答式的事务模型。每⼀个事务最少由⼀个要完成特定⽅法或功能的请求,和服务器端的⼀个应答组成。在这个例⼦中,这个事务从Alice的软电话发送⼀个INVITE请求到Bob的SIP URI开始。INVITE是⼀个SIP消息,它表⽰请求
者Alice想与Bob通话。INVITE请求包含⼀些头域。头域被称为属性,可以提供关于这个消息的额外信息。关于头域我们⼀会⼉将会详细说明它们。图1中的INVITE信息(F1)可能像这样:
INVITE sip:bob@biloxi SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi>
From: Alice <sip:alice@atlanta>;tag=1928301774
Call-ID: a84b 4c 76e66710@pc33.atlanta
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta>
Content-Type: application/sdp
Content-Length: 142
( Alice 's SDP not shown)
第⼀⾏⽂本是这个请求的⽅法名(INVITE)。后⾯的⾏是多个头域。这⾥只列出了最少需要的头域。先在这⾥对这些头域做⼀个简要的介绍:
Via头域包含Alice希望收到对于这个请求的应答的地址。也就是她告诉请求的接收者,应答应该发送到 pc33.atlanta。后⾯
的branch参数是这个事务的标识符。涨紧轮
To头域包含⼀个显⽰名(Bob)和⼀个SIP URI或者SIPS URI,这⾥是使⽤的SIP URI(sip:)。这个SIP UR
I就是这个请求要发送的⽬标。
From头域也包含⼀个显⽰名(Alice)和⼀个SIP URI或者SIPS URI,这⾥是使⽤的SIP URI(sip:)来指出请求的发起⼈。这个头域还包含了⼀个tag参数,这个参数包含了⼀个随机字符串(1928301774),这个字符串的数字会被软电话⾃动增加,它主要起到鉴别的作⽤,后⾯还会说明它。
led天花灯电源
Call-ID头域包含⼀个全局唯⼀标识符来标识这次呼叫。这个标识符使⽤⼀个随即字符串和软电话所在的主机名(或者IP地址)⼀起⽣成。这样,To头域、From头域和Call-ID这三个头域就可以唯⼀的确定了Alice和Bob的这条点对点的通信关系,并且将这个通信关系交给⼀个对
话(dialog)来处理了。
Cseq头域(命令序列)包含⼀个整数和⼀个⽅法名字。在这个对话中每⼀个新的请求都会增加这个整数的值,保证这个数值是有序的。
Contact头域包含⼀个SIP URI或者SIPS URI指出⼀个能够接触到Alice的直接路由,⼀般这个SIP URI由⽤户名和⼀个完全限定域
名(FQDN)构成。因为许多终端系统没有注册域名,所以也可以使⽤IP地址代替FQDN。Via头域向对⽅指出了这个请求的应答应该发送到哪⾥,⽽Contact头域向对⽅指出了将来的请求应该发送到哪⾥。
Max-Forwards头域限制了在这个请求传送到⽬的地的时候最多可以有多少跳。它包含⼀个整数,在每⼀跳这个整数都会被减少。
Content-Type头域描述消息体的类型(在这个例⼦⾥消息体采⽤了SDP描述,但是消息体内容没有给出)。
Content-Length头域指出了消息体的字节数。
在后⾯我们将完整的介绍SIP头域(RFC3261第20节)。
在会话中像媒体类型、编码⽅式、采样率等信息都不使⽤SIP描述,⽽是在消息体中使⽤其它会话描述协议的格式。这个例⼦中采⽤
了SDP描述(RFC2327)。
软电话不知道Bob或者拥有biloxi域名的SIP服务器,它将INVITE请求发送给为Alice提供服务的域名为atlanta的SIP服务器。关于Alice如何获得atlanta SIP服务器的地址,可以使⽤由Alice的软电话指定,或者使⽤DHCP探测到等⽅式。
atlanta SIP服务器是⼀个SIP代理服务器。⼀个代理服务器接收SIP请求,为请求的发送者转发请
求。在这个例⼦中,代理服务器接收到INVITE请求后发送⼀个100应答(Trying)给Alice的软电话。100应答(Trying)指出这个INVITE请求已经被代理服务器接收到,并且已被经进⼀步向⽬的地路由。SIP中的应答使⽤3位数字表⽰,每⼀个编号都表⽰⼀个描述短语。这个100应答(Trying)也同样包含和INVITE请求⼀样的To、From、Call-ID、CSeq和Via以及branch参数,这样可以使Alice的软电话知道这个应答是对应发送的INVITE请求的。atlanta代理服务器定位出biloxi代理服务器(这可能需要通过域名解析服务器(DNS)等实现,后⾯还会详细讲解)获得了它的IP地址,并且准备
把INVITE请求转发给biloxi代理服务器。在转发请求之前,atlanta代理服务器增加了⼀个额外的Via头域,这个Via头域包含⾃⼰的地址(这时候这个INVITE请求的第⼀个Via头域包含Alice的软电话的地址)。biloxi代理服务器接收到这个INVITE请求,并且也发送⼀
个100(Trying)应答给atlanta代理服务器指出它已经接收到这个INVITE请求,并正在处理这个请求。biloxi代理服务器知
道Bob的IP地址(这可能需要定位服务),它⼜在这个INVITE请求中加⼊了⼀个新的Via头域,值为⾃⼰的地址,然后它把这个INVITE请求发送给Bob的SIP电话。
Bob的SIP电话接收到这个INVITE请求,发送⼀个180(Ringing)应答,同时使⽤铃声通知Bob有⼀个来⾃Alice的呼叫,让Bob决定是否接听。这个180(Ringing)应答反向经过这两个代理服务器被发送到Alic
e。每⼀个代理服务器使⽤Via头域决定向哪⾥发送这个应答,并且把移除它⾃⼰添加的Via头域。这样,虽然只有初始的INVITE请求发送的时候使⽤了DNS服务和定位服务,⽽这个180(Ringing)应答没有使⽤,同时代理服务器也不需要记录整个通讯的状态,但是这个应答还是能够成功的发送给请求的发送者Alice。
当alice的软电话接收到180(Ringing)应答后,它将这个消息告诉给Alice,也许使⽤⼀个声⾳(彩铃)或者在Alice的屏幕上显⽰⼀个消息。
在这个例⼦中,Bob决定接听电话,当他按下接听按钮时,他的SIP电话发送200(OK)应答表⽰接受了这个呼叫。这个200(OK)应答包含⼀个消息体,消息体使⽤SDP描述Bob准备和Alice建⽴的会话的媒体类型等信息。这样,Alice和Bob交换了⼀次SIP信
息:Alice⽤INVITE请求发送⼀次给Bob,Bob⽤200(OK)应答发送⼀次给Alice。这个交换实现了基本的协商能⼒和简单的offer/answer模型。如果Bob不希望接听电话,或者他现在正忙(接听其它电话),那么他会发送⼀个错误应答⽽不是200(OK)应答。⼀个错误应答将不会建⽴会话。
Bob发送的200(OK)应答可能是这样的:
SIP/2.0 200 OK
Via: SIP/2.0/UDP server10.biloxi
绝缘软母排
;branch=z9hG4bKnashds8;received=192.0.2.3
Via: SIP/2.0/UDP bigbox3.site3.atlanta
;branch=z9hG4bK77ef 4c 2312983.1;received=192.0.2.2
Via: SIP/2.0/UDP pc33.atlanta
;branch=z9hG4bK776asdhds ;received=192.0.2.1
To: Bob <sip:bob@biloxi>;tag=a 6c 85cf
From: Alice <sip:alice@atlanta>;tag=1928301774
Call-ID: a84b 4c 76e66710@pc33.atlanta
CSeq: 314159 INVITE
Contact: <sip:bob@192.0.2.4>恐龙模型仿真
Content-Type: application/sdp
Content-Length: 131
(Bob's SDP not shown)
应答的第⼀⾏包含⼀个应答代码(200)和⼀个解释短语(OK)。其它⾏就是应答的头域。Via,To,From,Call-ID和CSeq头域的值都
从INVITE请求拷贝⽽来(这时候应该有3个Via头域,分别由Alice的SIP软电话,atlanta代理服务器,和biloxi代理服务器添
加)。Bob的SIP电话添加⼀个tag参数到To头域。以后所有的属于这个对话的请求和应答都要包含这个tag参数。
当Alice的软电话接收到这个200(OK)应答后,马上停⽌响铃并显⽰呼叫已经被接听了。最后,Alice发送⼀个确认信
息(ACK)给Bob的SIP电话,表⽰⾃⼰收到了最终应答(200(OK))。这个例⼦中的最终应答由Alice直接发送给了Bob,这是因为Alice的软电话从Contact头域⾥⾯可以得到Bob的地址信息。通过INVITA/200/
ACK的三步握⼿,SIP会话就建⽴起来了。关于SIP会话建⽴的详细步骤请参看RFC3261第13节。
现在Alice和Bob的多媒体会话已经建⽴起来了,他们可以发送通过SDP协商好的格式的媒体数据了。⼀般来说,媒体数据包的传输
与SIP消息的传输采⽤不同的通信⽅式。SIP消息⼤多通过代理服务器转发,⽽媒体数据多使⽤点对点的传输。
在会话过程中,⽆论是Alice还是Bob决定改变这个媒体会话,都要通过发送⼀个re-INVITE请求。这个re-INVITE请求包含新的媒体描
述(可能是SDP),它不会建⽴新的会话,⽽是修改当前已经存在的会话。对⽅接收到这个请求后,发送⼀个200(OK)同意这个改变,最后请求者发送ACK。如果对⽅不同意这个修改,可能会发送⼀个错误应答,⽐如488(不接受)。但是这个失败应答不会使已存在的会话退出,⽽是继续使⽤以前协商的媒体进⾏通信。关于修改⼀个会话的详细说明,请参看RFC3261第14节。
最后,Bob发送BYE消息挂断电话。BYE消息直接发送到Alice的软电话。Alice发送200(OK)确定接收到了BYE消息,并且终⽌这个会话。Bob不⽤发送ACK,因为ACK只有在接收到对INVITE的应答时才被发送。关于终⽌⼀个会话更详细的说明,请参看RFC3261第15节。
还有⼀个问题就是关于biloxi服务器如何获得Bob的位置。Bob的SIP电话开机的时候会向⼀个注册服务器发送REGISTER消
息。REGISTER消息的作⽤是将Bob的SIP URI或者SIPS URI与Bob当前使⽤的电话地址进⾏帮定,并将这个帮定信息保存到数据库中,这被称之为定位服务(location service)。biloxi代理服务器使⽤定位服务获得Bob的地址。注册服务器、代理服务器、定位服务器都是逻辑上的服务器,⽽不是物理上的服务器,所以他们可以位于同⼀台服务器上。

本文发布于:2024-09-22 04:33:31,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/257796.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:请求   应答   头域   发送   消息
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议