会话初始协议。SIP是IETF标准进程的一部分,它是在诸如SMTP(简单邮件传送协议)和HTTP(超文本传送协议)基础之上建立起来的(请求应答的通讯模式)。微信采用了自主研发的SYNC协议,他通过“握手”来同步消息(差值,降低数据量),采用Server通知/Client主动获取的交互方式。其优点包括:简化交互方式、增量传输数据、可靠有序传输、消息重传控制

SIP服务器是IP PBX的主要组件,负责建立网络中所有的SIP电话通话。SIP服务器也叫SIP代理服务器或注册服务器。

通常情况下,SIP服务器不参与媒体处理过程。在SIP网络中,媒体一般总是采用端到端协商的处理方式。在某些特殊情况或者业务处理中,例如Music On Hold,SIP服务器也会主动参与媒体协商。RTP要不要中转,就看sip server是如何处理了:1)如果sip server修改了sip里的SDP的地址和端口,那就要中转。你看你的cfg配置文件里是不是使用了use_media_proxy(). 2)sip server不修改SDP,就不中转。此时SDP里面是客户端的内网的IP和端口(一般默认是7078),如果客户端通过stun方式,那SDP里面的IP就是客户端的外网的NAT映射地址和端口。

简单的SIP服务器只负责会话的建立、维护和清除,不过多干涉呼叫。而相对比较复杂的SIP服务器,一般又称为SIP PBX,则不仅仅提供对基本呼叫、基本会话的支持,还提供丰富的业务,例如Presence、Find-me、Music On Hold等等。

大部分SIP服务器都是基于linux平台,典型代表为:OpenSER、sipXecx等。

也有部分SIP服务器是基于windows平台,典型代表为:miniSipServer、Brekeke等。

INVITE

主叫方Tesla首先发起 INVITE 消息到被叫方Marconi。INVITE 消息包含会话类型和一些呼叫所必须的参数。会话类型可能是单纯的语音,也可能是网络会议所用的多媒体视频,还可能是游戏会话。下面是消息体范例,我们来详细分析各个字段的意义。

INVITE sip:marconi@radio.org SIP/2.0
    <= 请求方法、请求地址(Request-URI)、SIP 版本号(目前都是 SIP/2.0)
       <= 请求地址一般就是被叫方地址,跟 MSN 中好友 eMail 地址类似

Via: SIP/2.0/UDP
lab.high-voltage.org:5060;branch=z9hG4bKfw19b
    <=SIP 版本号(2.0)、传输类型(UDP)、呼叫地址、
        <=branch是一随机码,它被看作传输标识
       
<=Via 字段中地址是消息发送方或代理转发方设备地址,一般由主机地址和端口号组成
        <=传输类型可以为 UDP、TCP、TLS、SCTP

Max-Forwards: 70
    <=最大跳跃数,就是经过 SIP 服务器的跳跃次数,主要是防止循环跳跃
    <=每经过一台代理服务器,该整数减一

To: G. Marconi
<sip:Marconi@radio.org>
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
    <=表示请求消息的发送方和目标方
        <=如果里面有用户名标签,地址要求用尖括号包起来
        <=对于 INVITE 消息,可以在 From 字段中包含 tag,它也是个随机码

Call-ID: 123456789@lab.high-voltage.org
   <=呼叫ID是由本地设备生成的,全局唯一值。每次呼叫该值唯一不变
        <=对于用户代理发送 INVITE 消息,本地将生成 From tag 和 Call-ID 全局唯一码,被叫方代理则生成 To tag 全局唯一码。这三个随机码做为整个对话中对话标识(dialog indentifier)在通话双方使用。

CSeq: 1 INVITE
    <=CSeq,又叫命令队列(Command Seqence),每发送一个新的请求,该数自动加1
* 以上几个字段是所有 SIP 消息体所必须的,其它头字段有些是可选的,有些在特定请求也是必须

Subject: About That Power Outage...
Contact: <sip:n.tesla@lab.high-voltage.org>
   <=Contact 是 INVITE 消息所必须的,它用来路由到被叫设备地址,也称为用户代理(UA)
Content-Type:
application/sdp
Content-Length: 158
    <=最后两位附属字段说明消息体类型以及字段长度

v=0    <=SDP版本号,目前都是 0
o=Tesla
2890844526 2890844526 IN IP4 lab.high-voltage.org    <=主叫源地址,类型等
s=Phone Call   <=主题
c=IN IP4
100.101.102.103   <=连接
t=0
0   <= 时间戳
m=audio 49170
RTP/AVP 0   <=媒体
a=rtpmap:0
PCMU/8000    <=媒体属性

<=从上面 SDP 消息体我们可以得出下面信息
        <=连接 IP 地址:100.101.102.103
        <=媒体格式:audio
       
<=端口号:49170
        <=媒体传输类型:RTP
        <=媒体编码:PCM u Law
        <=采样率:8000 Hz

180 Ringing

当 被叫方接收到 INVITE 请求消息后,将回复 180 Ringing。顾名思义,就是发回铃音,提示主叫方电话已连接上了,正等待被叫应答。被叫方接收到 INVITE 消息后也会发生响铃或者其它有呼入提示,这由被叫方设定(我们可以把它想象成我们自己设定手机铃声)。对于 180 响应又被称为“消息及时响应”,它是一种用来测试被叫状态的一种响应。因此它所包含的信息不多,具体 180 响应消息如下:

SIP/2.0 180 Ringing
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bKfw19b
;received=100.101.102.103    <=这里增加一个 received 参数,标识接收方 IP 地址
To: G. Marconi
<sip:marconi@radio.org>;tag=a53e42   <=上已提到,To tag 做为被叫方标识
From: Nikola
Tesla <sip:n.tesla@high-voltage.org>;tag=76341 <=要求很发送方 From tag 一致
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 INVITE
Contact: <sip:marconi@tower.radio.org>
Content-Length: 0
    <=对于 180 Ringing 响应,基本上就是将 INVITE 的 Via、To、From、Call-ID 和 CSeq 内容复制过来,对于首行标出 SIP 版本号,响应代码(180)和动作原因(reason phrase)
    <=注意这里 From 和 To 地址,因为它们用来指定呼叫方向,因此这里的 200 OK 响应并没有将地址对调,仍然保持原样。一点不同的是 To 头字段添加了由被叫方 Marconi 生成的 tag 标识

200 Ok

被叫响铃后,如果被叫用户 Marconi 接起电话,则发出 200 OK 响应。这个响应除了做为接通指示之外,还有一个功能是用来指定被叫允许的连接媒体格式,让主叫方确认是否可以接收该媒体。
消息体如下

SIP/2.0 200 OK
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bKfw19b
;received=100.101.102.103
To: G. Marconi <sip:marconi@radio.org>;tag=a53e42
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 INVITE
Contact: <sip:marconi@tower.radio.org>
Content-Type: application/sdp
Content-Length: 155
   <=头字段部分基本同上
v=0
o=Marconi 2890844528 2890844528 IN IP4 tower.radio.org
s=Phone Call
c=IN IP4 200.201.202.203
t=0 0
m=audio 60000 RTP/AVP 0
a=rtpmap:0 PCMU/8000

<=从上面 SDP 消息体我们可以得出下面信息
        <=终端 IP 地址:200.201.202.203
        <=媒体格式:audio
        <=端口号:60000
        <=媒体传输类型:RTP
        <=媒体编码:PCM u Law
        <=采样率:8000 Hz

ACK

通话前最后一步是主叫方确认 200 OK响应。该项确认证明连接被允许,即将使用另一种协议开始媒体连接。这另一种协议是上面在 SDP 消息段中所协商好的 RTP 格式。该 ACK 响应内容如下:

ACK sip:marconi@tower.radio.org SIP/2.0
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bK321g
Max-Forwards: 70
To: G. Marconi <sip:marconi@radio.org>;tag=a53e42
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 ACK
Content-Length: 0

BYE

通话完毕后,由被叫方 Marconi 首先挂机,发送 BYE 请求命令。注意这回由 Marconi 做为主叫方了,因此 Via 字段和 From、To 与 INVITE 字段有所不同。其实也就是倒置。

BYE sip:n.tesla@lab.high-voltage.org SIP/2.0
Via: SIP/2.0/UDP tower.radio.org:5060;branch=z9hG4bK392kf
Max-Forwards: 70
To: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
From: G. Marconi <sip:marconi@radio.org>;tag=a53e42
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 BYE
Content-Length: 0

200 OK

BYE 之后,要求被叫方发 200 Ok 确认,也就是让主叫知道被叫已经知道你挂断了。(注意这里所说的主被叫角色已经倒过来了)打个比方,通话之后,有一方要求挂机,另一方需要知道它已经挂机了。

SIP/2.0 200 OK
Via: SIP/2.0/UDP tower.radio.org:5060;branch=z9hG4bK392kf
;received=200.201.202.203
To: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
From: G. Marconi <sip:marconi@radio.org>;tag=a53e42
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 BYE
Content-Length: 0

到此,就是最简单的呼叫过程。该过程简单在于两个终端之间没有其它设备,完全的点对点连接,它们之间只需要知道对方 IP 地址即可。现实生活中这种呼叫形式是很少见的。

实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务。RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于低层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。

微信(Sync协议):

TCP长连接

如何获取新数据呢:

  1. 服务器端通知,客户端获取
  2. 客户端携带最新的SyncKey,发起数据请求
  3. 服务器端生成最新的SyncKey连同最新数据发送给客户端
  4. 基于版本号机制同步协议,可确保数据增量、有序传输
  5. SyncKey,由服务器端序列号生成器生成,一旦有新消息产生,将会产生最新的SyncKey。类似于版本号
  6. 服务器端通知有状态更新,客户端主动获取自从上次更新之后有变动的状态数据,增量式,顺序式。

Sip协议的更多相关文章

  1. 流媒体学习二-------SIP协议学习(基本场景分析 )

    作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.SIP业务基本知识 1.1 业务介绍 会话初始协议(Session Initiation Protocol) ...

  2. 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3941172.html,qq:1269122125. 上两章节简要的 ...

  3. 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...

  4. 基于GBT28181:SIP协议组件开发-----------第二篇SIP组件开发原理

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3937590.html,qq:1269122125. 上一节中讲的S ...

  5. 基于GBT28181:SIP协议组件开发-----------第一篇环境搭建

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3930018.html,qq:1269122125. SIP协议在安 ...

  6. SIP协议搭建电信级VOIP/IM运营平台--架构篇(sip集群)

    移动互联网的发展为整个VOIP通信行业开拓了新的战场,一时间各类即时通信软件如雨后春筝般冒了出来,再一次创造了移动互联网的发展神话.SIP协议做为音视频通信的首选标准,应用也越来越广泛. ------ ...

  7. SIP协议简单介绍

    sip协议是由IETF提出的IP电话信令协议,主要目的是为了解决ip网络中的信令控制,以及同软交换通信. sip协议类似http协议: 报文结构: start-line message-header ...

  8. 阐述:SIP协议是什么

    sip协议是什么?可能刚刚接触这个协议的朋友会掌握不好它的定义.那么首先我们要了解一下,目前企业中大多数VoIP应用都使用H.323协议,但是,随着越来越多的企业研究SIP协议,不久的将来基于SIP协 ...

  9. 深入浅出SIP协议

    传统电话是电磁波的通信,当电话技术发展到IP技术时代,SIP协议成为了电话通信标准协议,不仅可以通电话.还可以收发信息.视频.开会.放PPT.事实上,今天的通信业已全面采用SIP协议作为通信标准,无论 ...

  10. sipp模拟电信运营商VoIP终端测试(SIP协议调试)

    三大运营商都有SIP服务器,用来支持语音对讲,多媒体调度等功能,他们的平台可能不是标准的SIP协议会话. 为了应对没完没了的对接各个厂商的平台,这里再整理了一套协议脚本,毕竟全都是没有意义的无用功,标 ...

随机推荐

  1. 写点C++ 学习记录 充数

    #include "stdafx.h" #include <cstdlib> #include <iostream> using namespace std ...

  2. 20155210 2016-2017-2 《Java程序设计》第7周学习总结

    20155210 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 时间的度量: GMT(Greenwich Mean Time)时间:现在不是标准时间 世界时 ...

  3. C++之类和对象的特性

    简介:C++并不是一个纯粹的面向对象的语言,而是一种基于过程和面向对象的混合型的语言. 凡是以类对象为基本构成单位的程序称为基于对象的程序,再加上抽象.封装.继承和多态就成为面向对象程序. 1.掌握类 ...

  4. UVaLive 2531 The K-League (网络流)

    题意:有 n 个队伍进行比赛,每个队伍比赛数目是一样的,每场恰好一个胜一个负,给定每个队伍当前胜的场数败的数目,以及两个队伍剩下的比赛场数,问你冠军队伍可能是哪些队. 析:对每个队伍 i 进行判断是不 ...

  5. NSData与UIImage之间的转换

    1 //NSData转换为UIImage 2 NSData *imageData = [NSData dataWithContentsOfFile: imagePath]; 3 UIImage *im ...

  6. PhotoModeler Scanner教程

    Marking and Referencing 标记和校正 标记和校正是通过多张照片人工匹配共同特征的过程.点击一张图片的明显视觉特征,然后将它匹配到不同角度拍摄的其他图片的相同特征上. Approp ...

  7. day13(反射,BeanUtils包)

    反射, 获取字节码文件的方式: 方式一: 对象.getClass(); 方式二: 类名.Class; 方式三:   Class.forName(String Class); 通过字节码文件获取对象 定 ...

  8. ScrollView嵌套listview ,滚动问题。设置listview不滚动

    对于ListView内部的ListView,一般用来展示少量的列表数据. 内部的ListView的高度看起来是一个固定值且无法滑动,这个就比较蛋疼了.. 提供两种解决方案,方案的核心都是重新设置内部L ...

  9. 深入理解Aspnet Core之Identity(3)

    主题 账户管理一个比较常见的功能就是密码强度策略,Identity已经内置了一个通用的可配置的策略,我们一般情况下可以直接拿来用即可.本篇我会介绍一些Identity内置的密码策略类:Password ...

  10. redis的常用公共方法(2)

    之前已经写过一篇redis公共方法的使用(https://www.cnblogs.com/jhy55/p/7681626.html),可是发现在高并发的时候出现 Unknown reply on in ...