会话初始化协议(SIP)简介及应用

来源:互联网 发布:网络上lay是什么意思 编辑:程序博客网 时间:2024/05/02 02:20

下一代网络(NGN)与 SIP 协议

 随着移动通信技术的迅猛发展,将我们带入丰富多彩的 3G 多媒体信息时代。特别是互联网的飞速发展,越来越多的用户能够使用更快、更便宜的因特网联接,这使得像聊天应用、视频语音、在线游戏等需持续在线的应用实现成为可能。而传统电信网是为电话业务所设计的,那种拨一个号码并交谈的模式已经远远不能满足这种多媒体应用的需求,需要设计新的网络结构来支持。3G 网络作为下一代网络(Next Generation Network,NGN)其主要目标就是为用户提供包括语音业务和互联网数字业务在内的各种多媒体服务,其主要特征是将有线网络、互联网和无线网络进行无缝的融合。在这种条件下,软交换概念孕育而生。其作为下一代网络最受关注的焦点之一是把呼叫控制功能从媒体网关中分离出来,通过发送软件包的方式实现基本呼叫控制。这样将业务与呼叫控制分离,呼叫控制与数据承载相分离的 NGN 网络体系,使得网络各层之间的低耦合性能够有效的满足用户多样的、不断变化的需求。


图 1. 下一代网络分层体系结构

 在软交换设备众多的通信协议中,会话初始化协议(SIP)凭借其简单、易实现等多方面的优点成为下一代网络和 IP 多媒体子系统(IMS)的重要协议。SIP 协议是 IETF(因特网工程任务组)推出的一种信令协议,主要目的是在 IP 网络中建立、修改和终止多媒体会话的应用层协议。其主要的应用包括但不局限于语音、消息、视频、呼叫控制等。SIP 最初是用来发布多媒体内容,由于其简单和易扩展性于 1999 年称为 IETF 标准 [RFC2543]。随着 SIP 协议在互操作性和新特性的增强,于 2002 年形成新标准 [RFC3261]。

 SIP 协议是基于超文本传输协议(HTTP)和简单邮件传送协议(SMTP)的信令协议,下图描述了 SIP 协议在协议栈中的位置:


图 2. 协议栈结构

 SIP 协议虽然属于应用层协议,然而 SIP 本身并不提供任何服务。但是 SIP 是通信的基础,在 SIP 这个通信的基础上可以用来构建不同的服务。SIP 协议在建立和维持多媒体会话中,主要支持如下 5 个功能:

  • 检查终端用户的位置。无论被叫方在哪里均能确保呼叫达到被叫方,进行任何描述信息到定位信息的转换;

  • 检查用户参与会话的意愿程度。参与者在呼叫中能够引入其他用户加入或者取消其他用户的连接;

  • 检查媒体和媒体参数,允许与呼叫有关的组在支持特性上保持一致;

  • 在呼叫与被叫双方建立会话;

  • 发送和终止会话,修改会话参数,激活服务等会话管理操作;

SIP 协议的体系结构

 SIP 协议中的组成元素包含两个要素:SIP 用户代理(User Agent,UA)和 SIP 用户服务器(User Server,US)。用户代理是呼叫的终端要素,而用户服务器是处理与多个呼叫相关联信令的网络设备。在理想情况下,两个终端间的通信并不需要用户服务器的参与即可完成。但是现实总是比理想残酷,因为各个网络运营商、服务提供者希望对其网络的业务有所了解,固需要中间用户服务器的参与。

 图 3 所示是典型的网络结构,称之为“SIP 梯形”。SIP 终端构成通信的端点,它们负责发送和接受 SIP 请求和响应,同时它们也是多媒体流的终点。UA 可能是终端上的一个应用或者是专门的硬件设备。

 用户代理本身又可分为:客户机端(User Agent Client,用户代理客户机)和服务器端(User Agent Server,用户代理服务器)。用户代理客户机是发起请求的主叫应用;客户代理服务器是通话的被呼叫端,主要负责接受、重定向或者拒绝请求,给到来的请求发送响应。用户代理在发起呼叫的时候它是用户代理客户端,而当被呼叫的时候它是用户代理服务器端。

 用户服务器是 SIP 消息在到达其最终目的地前所经过的逻辑节点,这些服务器用于对请求进行路由和重定向,既进行名字解析和用户定位。主要包括以下几种服务器:

 有状态代理服务器(Proxy Server):负责接收和转发 SIP 请求。可解析并重构 SIP 消息的部分信息。但是这些重构不会影响请求或会话的状态;

 无状态代理服务器(Stateless Server):其负责将上游的请求向下游转发和将下游的响应向上游转发,其不纪录请求或会话的状态;

 重定向服务器(Redirect Server):其负责将请求的地址映射为新地址;它对请求进行重定向但是不参与事务的处理;

 位置服务器(Location Server):跟踪用户的位置;

 注册服务器(Registrar Server):负责接收和处理 REGISTER 请求的服务器;


图 3. SIP 典型网络结构


SIP 协议结构

 SIP 协议是一个分层的结构。分层结构的好处就是各个层次之间保持相对独立,层与层之间仅存在松散耦合关系。参见下图:


图 4. SIP 协议层次

 在 SIP 协议四层结构中,处于最底层的是采用 BNF 语法编码的语法和编码层;第二层是传输层用于控制终端如何发送请求和接收响应,以及控制服务端如何接受请求和发送响应;第三层是事务层,其用于控制请求和响应的匹配。SIP 协议中对事务的定义是:终端发送到服务器的一条请求和服务器端返回到终端的所有对该请求的响应(SIP 中存在一个请求对应多个响应,其中有多个临时响应但是最终响应只有一个,例如 INVITE)。该层还为上层提供事务的超时处理等。在 SIP 协议中定义了四种事务状态,每种状态都有自身的定时器、超时重发机制以及结束规则等。这四种事务状态为:INVITE 客户端事务、非 INVITE 客户端事务、INVITE 服务器端事务和非 INVITE 服务器端事务;最上层是事务用户层,用于创建客户端或服务器端事务。当需要发送 SIP 请求时,事务用户层创建一个客户端事务实例,将目的信息和传输协议等放在请求中发送。事务用户层包括上文提到的 SIP 两大要素之一 ---- 用户代理 UAC 和 UAS。其中 UAC 使用事务层创建和发送请求并接受响应;UAS 使用事务层接收请求并创建和发送响应。

 UAC:用户代理客户端负责填写请求 URI,发送和接收地址 From 消息头、To 消息头,标识惟一呼叫的 Call-ID 消息头,其还可添加用于指示 UAC 要求的 SIP 扩展的 Require 消息头和用于指示 UAS 支持的扩展的 Supported 消息头,用来标识事务先后顺序的 CSeq 消息头,标识事务分支参数的 Via 消息头,用户代理客户端可以为发送的 SIP 请求预设置一个路由集,在 Route 消息头中指定到达目的地之前需要经过的中间节点集合。

 UAS:如果请求中存在路由信息,按照路由信息进行检查;如果没有包含路由信息,则负责检查请求中的 URI 和 To 消息头已确认该请求的目标地址,如果其中任意一个失败,则本请求认为无效而发送错误响应。其次检查请求是否存在扩展的要求,如果 UAS 端不能满足扩展要求则返回错误。如果能够满足扩展要求,则进一步处理请求内容。UAS 处理完请求后,就会创建响应。如上所述,响应可能是多个临时响应,但最终响应只有一个。在创建响应时,响应消息的 From 消息头、Call-ID 消息头、CSeq 消息头、Via 消息头以及 To 消息头都从请求消息中复制过来。

建立 SIP 会话流程实例

 下面我们通过一个简单的场景例子来简单介绍一下 SIP 协议是如何建立、修改和控制多媒体会话的。这个事例介绍 SIP 的基本功能:用户定位、单方请求通信、通过协商会话参数建立会话和解除会话连接。

 Tom 和 Jerry 是非常好的伙伴,Tom 现在法国留学,快放暑假了,需要给在美国的伙伴 Jerry 打一个电话确定日程来接机。Tom 在他的 PC 上使用一个 SIP 的应用程序呼叫 Internet 上另一个 SIP 电话用户 Jerry。

1. 注册过程 :

 SIP 会话初始化协议的注册过程是建立用户当前 IP 地址与用户统一资源标识符之间的对应关系。首先,Tom 和 Jerry 的 SIP 应用程序或者硬件设备,需要在网络中注册。当登录 SIP 应用程序或硬件设备时,终端在网络中的注册过程会自动完成。若使用 SIP 应用程序,其已经于网络建立 IP 连接,若是硬件终端设备首先需要与网络建立连接,例如在 GPRS 情况下,终端与网关支持节点之间建立一个专用或通用的信令 PDP 上下文与网络建立连接。之后终端需要知道代理呼叫会话控制功能(P-CSCF)的地址。P-CSCF 是终端向网络中发送所有 SIP 消息的惟一入口。该实体在注册过程中用于 SIP 出站代理,注册完成后服务于所有其他 SIP 信令。该地址可以预先配置,在没有配置的情况下,终端可以在建立的通用或专用 PDP 信令上下文的过程中请求该地址。

 Tom 的终端首先会生成一个 REGISTER 请求,该请求中的相关信息从 Tom 的用户标识模块 (USIM) 的 IP 多媒体服务标识模块(ISIM)中获取。请求经过 P-CSCF 和 I-CSCF(问询呼叫会话控制功能)为 Tom 指定一个 S-CSCF(服务呼叫会话控制功能)。S-CSCF 负责根据请求信息建立用户标识与终端 IP 地址的对应绑定关系。

清单 1. 构造的 REGISTER 消息

REGISTER sip: telcomx.tel.com SIP2.0 From:<sip: tom@telcomx.tel.com>;tag=pohjaxx To:<sip: tom@telcomx.com> Via:SIP/2.0/UDP[4444::2:3:4:5];branch=xo93sle Route: sip:[5555::a:f:f:e];lr Contact:<sip:[4444::2:3:4:5]>;expires=600000 Call-ID: apb304a94sslfeiasle93aj11 Authorization:Digest username="tom@telcomx.tel.com",              realm="telcomx.tel.com",              nonce="",              uri="sip:telcomx.tel.com",              response=""CSeq: 25 REGISTER Content-Length:0

 该消息中 Route 标识请求路由的下一节点;Contact 中定义了 IP 地址与 SIP 统一资源标识符的绑定持续时间;Call-ID 和 CSeq 消息头惟一标识本次事务。注册消息经 P-CSCF 发送到 I-CSCF,I-CSCF 是 Tom 所在归属网的入口,接收 Tom 终端发起的每一次注册请求。I-CSCF 查询 HSS 服务器,根据请求中标识的需求能力,选择一个合适的 S-CSCF 为用户提供服务,并将请求发送到该 S-CSCF 节点上。

 S-CSCF 返回 401(未授权)响应要求 Tom 进行认证,则 Tom 的终端将发送第二个 REGISTER 请求,第二个请求包含相同的有关注册信息,并经过的路由与第一个 REGISTER 的路由完全相同。但是第二个 REGISTER 产生一个新的 Call-ID、Cseq 号码、branch 参数以及一个新的 From 标签,并且该 REGISTER 请求会带入新的安全认证标签信息。

清单 2. 构造带有认证信息的 REGISTER 消息
REGISTER sip: telcomx.tel.com SIP2.0 From:<sip: tom@telcomx.com>;tag=6e87wa9 To:<sip: tom@telcomx.tel.com> Via:SIP/2.0/UDP[4444::2:3:4:5];branch=u2x9s7 Route: sip:[5555::a:f:f:e];lr Contact:<sip:[4444::2:3:4:5]>;expires=600000 Call-ID: apb304a94sslfaser2le93aj22 Authorization:Digest username="tom@telcomx.tel.com",              realm="telcomx.tel.com",              nonce="A34Cm+FVa73YTUGpGMBIs34P,algorithm=AKAv1-MD5",              uri="sip:telcomx.tel.com",              response="6629fac4969a87854152369874c43fd1"CSeq: 47 REGISTER Content-Length:0
 注意,第二次注册请求会填写相应的认证密钥信息。认证过程成功,S-CSCF 将对 Tom 进行注册。即 S-CSCF 创建一个绑定关系,绑定 To 消息头中公共用户标识和 Contact 中的 IP 访问地址。随后 S-CSCF 向终端发送响应。
清单 3.REGISTER 消息的响应
SIP/2.0 200 OK Via:SIP/2.0/UDP icscf1.tel.com;branch=21ksi9 Via:SIP/2.0/UDP pcscf1.tel.com;branch=2x7as2 Via:SIP/2.0/UDP[4444::2:3:4:5];branch=u2x9s7 From:<sip: tom@telcomx.tel.com>;tag=6e87wa9 To:<sip: tom@telcomx.tel.com>;tag=kotimaex Contact:<sip:[4444::2:3:4:5]>;expires=600000 Service-Route:sip:telcomx@scscf1.tel.com;lr Call-ID: apb304a94sslfaser2le93aj22 CSeq: 47 REGISTER Content-Length:0

 S-CSCF 将自己的访问地址通过 Service-Route 消息头返回给终端,该响应送回的路径是所有接收过 REGISTER 请求的 CSCF,因为各个 CSCF 在接收 REGISTER 时都把自己的地址放在了 Via 消息头的顶端。这时终端注册已经成功。


图 5. SIP 注册流程

2. 会话建立:

 Tom 通过 Jerry 的 SIP 标识呼叫 Jerry,这个统一资源标识符称作 SIP URI。SIP URI 很像一个 E-mail 地址,典型的统一资源标识符包括一个用户名和主机名。假设 Jerry 的统一资源标识符为 sip: jerry@california.tel.com。主机名 california.tel.com 是 Jerry 的本地 SIP 服务供应商即 Jerry 的归属域。Tom 使用自己的统一资源标识符发送请求。Tom 的统一资源标识符:sip: tom@telcomx.tel.com。其中 telcomx.tel.com 是 Tom 的 SIP 服务供应商。

 Tom 的软电话发送一个含有 Jerry 的统一资源标识符地址的 INVITE 请求。INVITE 是 SIP 的一个请求,其用于请求方发起请求希望服务方应答。建立会话的过程主要有以下几步:

 使用 Jerry 的统一资源标识符创建 INVITE 请求;

 在 Contact 消息头中设置自己的访问 IP 地址与端口号,确保对端 Jerry 所有的响应都能直接发回到该终端;

 将注册过程中所存储的 S-CSCF 访问地址信息添加到消息的 Route 中,这样避免每次发送 SIP 请求需要通过 I-CSCF 查找 S-CSCF 的开销;

 将出站代理 P-CSCF 的访问地址也添加到 Route 消息头顶端生成消息路由;

 请求按照 Route 顶端地址发送到出站代理 P-CSCF 上,去除 Route 中标识自己的访问条目,在 Record-Route 和 Via 中添加 P-CSCF 访问条目,确保请求的响应路由能够返回到自身节点。转发 INVITE 请求到 Route 定义的下一个节点;

 请求发送到 S-CSCF 节点上,首先去除 Route 中标识自己的访问条目,将 S-CSCF 访问条目添加到 Record-Route 和 Via 中,查询 DNS 服务获得用户 Jerry 的 SIP URI 所归属的域,将请求转发到 Jerry 所归属域的 I-CSCF 节点上;

 在 Jerry 归属域的 I-CSCF 节点上,首先添加自己的访问条目并将该访问条目添加到 Via 消息头中,查询 SLF 获取 Jerry 的 HSS 服务器地址,并查询 HSS 获取与用户 Jerry 相绑定的 S-CSCF 节点访问地址,将 INVITE 请求转发到该 S-CSCF 节点上;

 请求到达 Jerry 归属域的 S-CSCF 节点上,首先从路由 Route 消息头中删除标识自己的访问条目,在 Record-Route 中添加该访问条目,将用户 Jerry 的统一资源标识符替换为注册的联系地址,转发请求到下一个节点;

 消息到达 Jerry 的 P-CSCF 代理节点上,其转发请到用户 Jerry 的 IP 地址上;

 这时 INVITE 请求已经到达用户 Jerry 的终端上,该终端设备保存 Tom 的 Contact 消息头,生成相应响应信息,并设置响应 Contact 消息头为 Jerry 终端的 IP 地址 / 端口,将 Record-Route 和 Via 消息头复制到响应中,并基于 Via 消息头发送响应;

 当响应到达用于 Tom 终端时,Tom 终端也会保存用户 Jerry 的 Contact 信息,这样双方都知道对方直接访问的 IP 地址和端口,之后可以直接发送请求到对方终端了。

图 6. SIP 会话建立路由过程


清单 4.INVITE 请求

INIVTE sip:jerry@california.tel.com  Via: SIP/2.0/UDP[4444::2:3:4:5];branch=8ulse1  Route:<sip:[5555::a:b:c:d];lr>  Route:<sip:telcomx@scscf1.tel.com;lr>  Contact:<sip:[4444::2:3:4:5]:1537>  From:<sip: tom@telcomx.tel.com>;tag=6e87wa9  To:<sip: jerry@california.tel.com>  Call-ID: apb03a0s09dkjdfoaidy49555  CSeq: 1 INVITE  Max-Forwards: 70  Content-Length:183 (必须的空行)(SDP 请求消息体)

清单 5. 183“会话进行中”响应
SIP/2.0 183 Session in Progress  Via: SIP/2.0/UDP scscf2.california.tel.com;branch=12fd3  Via: SIP/2.0/UDP icscf2.california.tel.com;branch=24re3  Via: SIP/2.0/UDP scscf1.tel.com;branch=64w32  Via: SIP/2.0/UDP pcscf1.tel.com;branch=412d2  Via: SIP/2.0/UDP[4444::2:3:4:5];branch=8ulse1  Route-Route:<sip pcscf2.california.tel.com;lr>  Route-Route:<sip scscf2.california.tel.com;lr>  Route-Route:<sip scscf1.tel.com;lr>  Route-Route:<sip pcscf1.tel.com;lr>  Route:<sip:telcomx@scscf1.tel.com;lr>  Contact:<sip:[4444:5:6:7:8]:1078>  From:<sip: jerry@california.tel.com>;tag=e42q14d  To:<sip: tom@telcomx.tel.com>;tag=6e87wa9  Call-ID: apb03a0s09dkjdfoaidy49555  CSeq: 2 183  Max-Forwards: 70  Content-Length:165 (必须的空行)(SDP 请求消息体)

 Tom 发送 INVITE 请求后需要等待 Jerry 的响应,如果等待超时则需要重传一个 INVITE 请求,如果 128 秒后仍收不到响应,就宣告本次会话建立失败。例如本例中该呼叫漂洋过海,因此到达 Jerry 终端可能超过超时等待时间,为了避免 Tom 终端频繁地重发 INVITE 请求,P-CSCF 收到 INVITE 请求后,返回一个 100 Trying 临时响应。这表明现在开始 P-CSCF 负责 INVITE 的重传工作,以此类推。


图 7. SIP 会话信号流程图

3. 会话媒体参数协商:

 Tom 终端在发送第一个 INVITE 请求中带有一个 SDP 的消息体,该消息体描述 Tom 希望在本次会话中使用的所有媒体参数信息,包括媒体类型、各类媒体支持的编码解码类型;在 Jerry 终端的第一个响应中会带入 INVITE 请求的 SDP 消息体应答,可能拒绝某些提议的媒体类型,缩减媒体编码解码类型,仅剩下双方都支持的编码解码。Tom 终端收到第一个应答后,其必须最终决定使用哪种编码解码类型,并给被叫方发送 PRACK 消息,将第二个 SDP 媒体协商参数消息发出,确定在本次会话中每种媒体类型采用的惟一编码解码类型。Jerry 终端接受第二次提议并返回一个确认应答。


图 8. 会话协商信号流程图

 通过会话媒体协商,双方商定最终使用的媒体参数建立媒体连接,实现通话。

4. 会话的释放:

 Tom 和 Jerry 通话完毕,这是 Jerry 会按下终端设备的红色挂机按钮断掉呼叫。这是他的终端生成一个 BYE 请求,沿着与其他请求相同的路由发送给 Tom 的终端,同时还会释放本次会话建立的媒体 PDP 上下文。Tom 的终端收到该请求后也会立刻释放它的 PDP 上下文,同时向 Jerry 终端返回一个 200(OK) 的响应来应答 BYE 请求。注意路径的 CSCF 和所有的 AS 都会清除与本次会话有关的所有会话状态和信息。


清单 6. BYE 请求

BYE sip:[4444::2:3:4:5] SIP/2.0 Route:<sip:pcscf2.california.com;lr> Route:<sip:scscf2.california.com;lr> Route:<sip:scscf1.tel.com;lr> Route:<sip:pcscf1.tel.com;lr> To:<sip: tom@telcomx.tel.com>;tag=6e87wa9 From:<sip: jerry@california.tel.com> Call-ID: w273alskdjb732s07yad22 CSeq: 15 BYE Max-Forwards: 70 Content-Length:0

 从上述报文可以看到 From 和 To 消息头的信息互换了,因为本次消息是从用户 Jerry 一方发出的。


图 9. SIP 会话释放流程图
  

Android Platform 对 SIP 的支持

 Android 2.3 Platform 增加了对 SIP VOIP 的支持。新增了 SIP 协议栈和相应的 framework API 供开发者创建基于 SIP 的 VOIP 通信服务应用程序。android.net.sip 包是 Android framework API 提供的对 SIP 协议支持的类库,其中最核心的类是 SipManager,该类负责创建、初始化 SIP 连接和提供相应 SIP 服务的访问,这里简单介绍 SipManager 的一些重要方法:

 SipManager.open():该方法根据 SipProfile 实例中记录的 SIP 账户,归属域等信息进行注册;

 SipManager.makeAudioCall():该方法根据传入的参数创建一个 outgoing 呼叫;

 SipManager.takeAudioCall():该方法根据传入的 intent 接收一个 incoming 呼叫;

清单 7. 部分 andriod API 片断

public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // 创建 sipManager 实例,如果 sm 为空,表明该设备不能支持 SIP API    SipManager sm = sipManager.newInstance(this);    … …   // 创建 SipProfile 实例并注册   SipProfile.builder sp = new SipProfile.builder(username, domain);    sp.setPassword(password);    SipProfile me = sp.builder();         // 定义 android 事件通信对象实例,用于多个 service 之间消息传递   Intent intent = new Intent();    intent.setAction(“android.sip.INCOMING_CALL”);    PendingIntent pendingIntent =      PendingIntent.getBroadcast(this,0,intent, Intent.FILL_IN_DATA);   sp.open(me, pendingIntent, null);         // 必须添加 registrationListener    sp.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {       … … });  } … … public void outGoingCall() {     int timeOut = 30;   // second     SipAudioCall.Listener listener = new SipAudioCall.Listener() {         public void onCallEstablished(SipAudioCall call) {             call.startAudio();             call.setSpeakerMode(true);             call.toggleMute();         }              Public void onCallEnded(SipAudioCall call) {}  };          // 创建一次媒体呼叫,如果在 timeOut 时间内没有建立起呼叫,则终断本次呼叫    Call =     sp.makeAudioCall(me.getUriString(), “jerry@california.tel.com”,listener, timeOut); } … … public void inComingCall(Context context, Intent inComingIntent) {     final int timeout = 30;     SipAudioCall.Listener listener = new SipAudioCall.Listener() {         public void onRinging(SipAudioCall call, SipProfile caller) {             // 对呼入进行响应,如果在 timeout 时间内没有响应,则终断本次呼叫            call.answerCall(timeOut);         }  };       SipAudioCall inComingCall = sp.takeAudioCall(inComingIntent, listener);  inComingCall.answerCall(30);  // 启动媒体建立呼叫连接 inComingCall.startAudio();  inComingCall.setSpeakerMode(true); … … }

清单 7 列举了部分 andriod API 片断,主要目的是对 SIP 协议栈 API 重要核心方法的使用的简单介绍,有兴趣的朋友们可参照 Android 开发者网站。

SIP 的开源协议栈

 目前具有代表性的 SIP 协议栈开源项目有:OPAL、VOCAL、oSIP 等。OPAL 设计目的是包含任何电话通信协议,故底层进行了高度的抽象化。其使用 openh.323 体系结构,实现了 SIP 和 H.323 的支持;VOCAL 是目前功能最完善,使用者最多的开源 SIP 协议栈,对 SIP 各种服务器的功能也支持的非常完善。oSIP 采用 ANSI C 编写,结构简单小巧,但并不支持高层 SIP 会话控制 API,主要提供解析 SIP/SDP 消息的 API 和事务处理状态机。此外还有 sipX、Ser 等,读者可根据自己的需要选择。

总结

 SIP 协议作为第三代网络中重要的软交换协议发挥了重要的作用。本文简单介绍了 SIP 的体系组成结构以及协议组成部分,并通过一个场景简单介绍了 SIP 协议参与整个会话建立的过程。


http://tech.ddvip.com/2013-07/1373356628198650.html




原创粉丝点击