P2P通信标准协议(四)之SIP

2024-05-09 01:32
文章标签 sip 通信 p2p 标准协议

本文主要是介绍P2P通信标准协议(四)之SIP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在前面几篇文章中我们介绍了建立p2p通信的一般协议(簇),以及一种完整的NAT传输解决方案ICE,
但是对于多用户的通信情况,还有一些通用协议来实现标准化的管理,如之前讲过的SDP和SIP等,SIP(Session Initiation Protocol),
是属于应用层的控制协议,主要用于在一个或多个参与者之间创建,修改和中止会话(sessions).会话的类型包括IP电话,
多媒体流分发和多媒体会议等.

SIP简介

SIP邀请(invitations)用于创建携带会话描述(如SDP信息)的会话,允许参与者使用一系列兼容的媒体类型.
SIP使用一种叫代理服务器的元素来帮助对用户当前位置进行转发,对用户进行验证和授权,并为用户提供相应的功能.
SIP同时也提供了注册函数以允许用户上传他们的当前地址供代理服务器使用.SIP协议运行在多个不同的传输协议之上.

SIP支持5个方面来建立和中止多媒体会话:

  • 用户地址(User location): 决定了用来通讯的终端系统.
  • 用户状态(User availability): 决定了被呼叫端的是否愿意加入通讯.
  • 用户性能(User capabilities): 决定了多媒体类型和媒体使用的参数.
  • 会话建立(Session setup): "响铃",在呼叫端和被呼叫端建立起会话.
  • 会话管理(Session management): 包括传输和中止会话,修改会话参数以及调用服务.

SIP不是一个垂直集成的通讯系统,而是作为一个组件与其他协议共同运作,如RTP等实时传输协议等.另外SIP不提供服务,
只提供可以用来实现各种服务的原语.比如,SIP可以定位用户并且传输一个不透明的对象到其当前地址.如果这个原语用来
传输SDP,终端就能得知会话的一些参数;如果同样的原语用来传输一张照片,那也可以实现一种"显示来电者头像"的服务.
由此可见,一种原语通常用来实现多种不同的服务.

SIP工作过程

下图描述了SIP的基本功能:定位一个终端,产生通讯请求,建立会话以及结束会话.

                 atlanta.com  . . . biloxi.com.      proxy              proxy     ..                                       .Alice's  . . . . . . . . . . . . . . . . . . . .  Bob'ssoftphone                                        SIP Phone|                |                |                ||    INVITE F1   |                |                ||--------------->|    INVITE F2   |                ||  100 Trying F3 |--------------->|    INVITE F4   ||<---------------|  100 Trying F5 |--------------->||                |<-------------- | 180 Ringing F6 ||                | 180 Ringing F7 |<---------------|| 180 Ringing F8 |<---------------|     200 OK F9  ||<---------------|    200 OK F10  |<---------------||    200 OK F11  |<---------------|                ||<---------------|                |                ||                       ACK F12                    ||------------------------------------------------->||                   Media Session                  ||<================================================>||                       BYE F13                    ||<-------------------------------------------------||                     200 OK F14                   ||------------------------------------------------->||                                                  |图 1: SIP会话建立

图中描述了两个用户Alice和Bob交换SIP信息的过程.(信息表示为Fn.) 首先,Alice在其PC上使用了SIP终端(假设是软件电话),
并且通过互联网打给Bob. 其中我们看到有两个代理服务器atlanta和biloxi,用来帮助双方进行会话建立.这个典型的排列经常
被称为SIP之梯(SIP trapezoid).

Alice呼叫Bob时,使用的是Bob的SIP身份信息,一种特定类型URI称为SIP URI,形式和E-mail地址类似,包含了用户名和主机名.
在本例中,Bob的地址为sip:bob@biloxi.com,biloxi是Bob的SIP服务提供商;同样,Bob联系Alice时也通过其SIP地址sip:alice@atlanta.com
来进行通信. SIP同样提供了安全的链接SIPS,和HTTPS类似,主要通过TLS进行内容加密, 加密的地址格式为sips:alice@atlanta.com

SIP基于一种类HTTP的请求/响应传输模型.每次传输包含一个调用了特定方法或函数的请求,以及至少一个响应.在本例中,
传输开始时Alice发送了一个INVITE请求到Bob的SIP URI. INVITE请求包含一系列头部(header)字段.头部字段被称为属性,
提供了关于报文的额外信息. 产生INVITE请求的终端包含了一个独特的通话标识符,目的地址,Alice的地址以及Alice
希望与Bob建立的会话的类型信息. 一个INVITE请求的例子如下,其中Alice的SDP信息没有显示出来:

  INVITE sip:bob@biloxi.com SIP/2.0Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhdsMax-Forwards: 70To: Bob <sip:bob@biloxi.com>From: Alice <sip:alice@atlanta.com>;tag=1928301774Call-ID: a84b4c76e66710@pc33.atlanta.comCSeq: 314159 INVITEContact: <sip:alice@pc33.atlanta.com>Content-Type: application/sdpContent-Length: 142(Alice的SDP信息,略)图 2: Alice发送的请求报文

其中第一行包含了方法的名字(INVITE).后面的一些行则是一系列头部区段,各个头部字段的含义在下一节会说到.

由于Alice不知道Bob的准确地址,因此报文会先发送到Alice的SIP服务提供商,atlanta.com. 这个地址是可以在Alice
的终端(软件电话)上面进行配置的,当然也可以通过DHCP之类的协议来发现. SIP服务器接收SIP请求并按照其目的
进行转发. 在本例中, 代理服务器接收INVITE请求后,给Alice返回100(Trying)响应,表示请求正在进行转发.
SIP响应用一个三位数来表示状态,包含了和INVITE请求中同样的To, From, Call-ID, CSeq 和 branch(via内)参数,
从而允许Alice的终端将其与请求相联系. 代理服务器atlanta.com通过DNS等方法得到Bob的服务提供商地址.
并且在转发的报文中的via字段加上自己的地址信息. biloxi.com代理服务器接收到INVITE请求,并且返回100响应给
atlanta.com. 代理服务器查找其数据库(通常称为定位服务),其中包含了Bob的当前IP地址. 同时代理在转发请求前
也在头部的via字段加上自己的地址.

Bob的终端(SIP电话)接收到INVITE请求后,会提示Bob这是来自Alice的来电.同时Bob的终端返回180响应,
表示正在呼叫,响应一直转发回到Alice的终端,从而使Alice也能知道对方电话正在响.每个代理都通过头部的Via
字段来决定响应的发送方向,并且从via顶部去掉自己的地址信息. 因此虽然发送请求的时候用到DNS和定位服务,
但是发送响应的时候则不需要.

在本例中,Bob决定接起电话. 此时Bob的SIP电话发送200响应表示呼叫被应答.200响应包含了信息体(SDP)
表明Bob希望建立的会话类型.因此,这形成了两次SDP信息交换过程:Alice发送给Bob,然后Bob发送给Alice.
这个两次交换提供了基本的协商能力,并且基于简单的offer/answer模型. 如果Bob
不想接电话或者正在与别人通话,就会返回一个错误响应,从而不建立多媒体会话. Bob发送的200响应结构大体如下:

  SIP/2.0 200 OKVia: SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bKnashds8;received=192.0.2.3Via: SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1To: Bob <sip:bob@biloxi.com>;tag=a6c85cfFrom: Alice <sip:alice@atlanta.com>;tag=1928301774Call-ID: a84b4c76e66710@pc33.atlanta.comCSeq: 314159 INVITEContact: <sip:bob@192.0.2.4>Content-Type: application/sdpContent-Length: 131(Bob的SDP信息,略)图 3: Bob发送的响应报文

Bob的SIP电话增加了一个tag参数到报文头部,这个tag会被两个端点合并到对话里,并且会在(本次通话)所有以后的请求和响应中包含.
Contact头包含了一个Bob能直接连接的URI,Content-Type 和 Content-Length表示消息体(没贴出来)的格式信息.
在本例中,代理服务器也可以拓展自己的功能,比如当接收到Bob返回的486(Busy Here)响应,则可以向Bob的语音信箱等
发送INVITE请求;一个代理服务器可以同时向多个地址发送请求,这种并行查找的特性通常称之为分叉(forking).

在200(OK)响应返回到Alice的软件电话上之后,电话停止响铃,并通知Alice对方已经接听,同时发送一个ACK报文到Bob
的终端,表示响应已经收到. 在本例中,ACK直接发送给Bob,而不通过两个代理服务器,是因为两个端点都知道了对方的地址,
因此不需要再通过代理去查找.

收到ACK之后,Alice和Bob就可以互相通信了. 通信完成之后,假设Bob先挂断电话,并产生一个BYE报文,直接发送给Alice,
Alice收到后确认请求,并返回200(OK)响应,从而结束此次会话.注意这里没有发送ACK,因为ACK只有在确认INVITE请求的响应时才发送.

注册(Registration)是另一个SIP常用的操作. 用户通过注册使得代理服务器能知道其当前的地址信息. 例如Bob
可以在初始化时,向biloxi.com发送注册请求(REGISTER),后者也称为注册商(registrar).
注册商会将Bob的SIP URI和其当前地址相关联起来(通常称为绑定),并把这个映射信息存储到服务器端的数据库中,
亦即上文说到的定位服务. 通常注册服务器和对应域名的代理服务器都是同一地址的,因此要知道SIP服务器的类型的
区别体现在逻辑上而不是物理上.

SIP协议结构

SIP是一个分层的协议,这意味着其行为由一系列同级但独立的段(stage)描述. SIP的最底层为语法和编码,其中编码由
BNF语法(Backus-Naur Form grammar)指定; SIP第二层为为运输层(transport layer),定义了客户端和服务端如何发送和接收
请求和响应;第三层为事务层(transaction layer),事务层是SIP的基础组件,一次事务包括发送的请求和对应的响应,
事务层处理应用层的重传,请求/响应匹配和超时等;事务层之上称为事务用户(TU, transaction user),每个SIP
实体(除了无状态的代理),都是一个TU.

所有的SIP元素,包括用户客户端(UAC),服务器(UAS),无状态(stateless)或者全状态(stateful)的代理,
以及注册商,都包含一个区分彼此的内核(core). 其中除了无状态的代理,其他元素的内核都是事务用户.
UAC和UAS的内核行为依赖于方法,对于所有方法有一些通用规则,这里不细说. 对于UAC而言,这些规则支配
着请求报文的构造.

SIP报文格式

SIP是基于文本(text-based)的协议,并且使用UTF-8字符集.一条SIP报文要么是从客户端到服务端的请求,
要么是服务端到客户端的响应;两种类型的报文都包含一个起始行,一个或者多个头部区域,一个表示头部结束的空行,
以及(可选的)正文部分(message body),每个部分以CRLF隔开:

     generic-message  =  start-line*message-headerCRLF[ message-body ]start-line       =  Request-Line / Status-Line

除了字符集的区别,大多数SIP的报文和头部语法都与HTTP/1.1相同,虽然如此,但SIP不是HTTP协议的拓展.

SIP Request

SIP请求的报文首行都包含一个请求行(Request-Line),请求行又包括方法名,请求URI以及协议版本,
并以SP(空格)分割除了在行尾,请求行不允许出现任何回车(CR)和换行(LF),元素中也不能出现行间的空字符(LWS, linear whitespace).

  Request-Line  =  Method SP Request-URI SP SIP-Version CRLF

其中:

  • Method: 表示方法,RFC3261定义了六个方法,分别是:
    • REGISTER: 用来注册联系人信息.
    • INVITE, ACK, CANCEL, BYE: 这四个方法用于会话的建立.
    • OPTIONS: 用来发现服务器的性能(capabilities).
  • Request-URI: 即SIP或者SIPS URI,用来表示请求要送往的服务或用户信息,其中不能包括控制字符,
    也不能包含在"<>"之中.
  • SIP-Version: SIP的版本号,与RFC3261对应的是"SIP/2.0".和HTTP/1.1的处理类似,但不同点为SIP处理
    版本号是以字符串的格式,虽然这在实践中并没什么太大关系.

SIP Response

SIP响应与请求不同,其起始行为状态行(Status-Line),状态行包括协议版本,状态码以及对应的状态文字说明,
和请求行类似,个元素以空格分隔,中间也不能出现换行和回车.

Status-Line  =  SIP-Version SP Status-Code SP Reason-Phrase CRLF

状态码(Status-Code)由3位数字组成,表示请求的结果. 状态码的第一位表示响应的种类:

  • 1xx(表示100-199,下同): 临时响应(Provisional),表示请求已经被收到,但还在处理之中.
  • 2xx: 成功(Success), 请求被成功接收,理解以及被接受.
  • 3xx: 重定向(Redirection), 可能需要重新选择发送地址以完成请求.
  • 4xx: 客户端错误(Client Error), 请求包含错误的语法,或者不能被服务器完成.
  • 5xx: 服务端错误(Server Error), 服务器处理一个合法的请求失败.
  • 6xx: 失败(Global Failure),

Header Fields

SIP报文的头部和HTTP的头类似, 也有同样的性质,如在多个头部区域指定同一个属性的值时可以合并成一个头部,
并使field-value以逗号分隔等,头部的格式如下:

  field-name: field-value

冒号两边可以加任意空格,但是一般不建议这样做,而是使filed-name和冒号间不留空格,并使冒号和field-value只见留一个空格.
以图2中Alice的Request请求报文为例,大致介绍其中一些常见的Header field-name:

  • Via: 包含了发送方想接受此次请求对应响应的地址,这里是pc33.atlanta.com,
    并且还包含了识别此次传输事务的分支参数(branch parameter).
  • Max-Forwards: 用来限制请求的最大跳数(max hops),在每个hop之后递减少.
  • To: 包含了此次请求的目的用户的显示姓名Bob(display name)以及SIP/SIPS URI(sip:bob@biloxi.com)
  • From: 包含了此次请求的发送方的显示姓名Alice和URI, 除此之外还有一个tag参数,包含了随即的字符串,
    将用于添加在URI中,主要用于验证和区分.
  • Call-ID: 包含了此次通话中全局不同的标识,由随机字符串和发送端的主机名或IP地址组合而成.To,From和Call-ID
    字段完全定义了一个Alice和Bob的端到端的SIP关系,并表示为当前对话(dialog).
  • CSeq: 或者写为Command Sequence,包含了一个整数(CSeq号)和方法名,CSeq号在本次对话中随着每次新的请求而递增.
  • Contact: 包含代表直接连接Alice的SIP/SIPS URI. 和Via段不同的是,Via告诉其他单位要往那发送响应,
    而Contact告诉其他单位要往哪发(以后的)请求.
  • Content-Length: 消息体的长度.
  • Content-Type: 消息体(message body)的格式, 如SDP信息则为"application/sdp",关于SDP可以参考前一篇博客P2P通信标准协议(三)之ICE.

后记

本文简单介绍了SIP协议的结构和报文格式, 其中有很多细节都没有深入, 因此篇幅只有原文/RFC3261的十分之一,
如果要根据协议来设计实际的应用,还是需要仔细看一遍协议的原文. 至此, P2P通信系列的介绍也就告一段落了.
P2P的去中心化,一直是个很令人振奋的话题,无论是在信息技术上,还是在金融,政治上,都有无限潜力.
最近的一系列文章主要是P2P入门以及实现简单的VOIP应用, 下一阶段应该会研究下内容分发协议(如bittorrent),
不过以我的拖延症来看,那肯定是很久之后的事了.

本文连接http://www.cnblogs.com/pannengzhi/p/5103914.html
个人博客 jekyll.pppan.net
文章可自由转载,但请注明出处

这篇关于P2P通信标准协议(四)之SIP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972007

相关文章

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

C++编程:ZeroMQ进程间(订阅-发布)通信配置优化

文章目录 0. 概述1. 发布者同步发送(pub)与订阅者异步接收(sub)示例代码可能的副作用: 2. 适度增加缓存和队列示例代码副作用: 3. 动态的IPC通道管理示例代码副作用: 4. 接收消息的超时设置示例代码副作用: 5. 增加I/O线程数量示例代码副作用: 6. 异步消息发送(使用`dontwait`标志)示例代码副作用: 7. 其他可以考虑的优化项7.1 立即发送(ZMQ_IM

VB和51单片机串口通信讲解(只针对VB部分)

标记:该篇文章全部搬自如下网址:http://www.crystalradio.cn/thread-321839-1-1.html,谢谢啦            里面关于中文接收的部分,大家可以好好学习下,题主也在研究中................... Commport;设置或返回串口号。 SettingS:以字符串的形式设置或返回串口通信参数。 Portopen:设置或返回串口

深入理解TCP通信

这大概是自己博客上面第三次写TCP通信demo了,总是写同样的内容也不太好啊,不过每一次都比前一次进步一点。这次主要使用了VIM编辑工具、gdb调试、wireshirk、netstat查看网络状态。 参考《C++服务器视频教程》、《Unix网络编程》 一、VIM常用命令 vim server.cpp #打开一个文件:w 写入文件:wq 保存并退出:q! 不保存退出显示行号

电子电气架构---私有总线通信和诊断规则

电子电气架构—私有总线通信和诊断规则 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节能减排。 无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事.而不是让内心的烦躁、

DoIP-ISO 13400-1 道路车辆-基于互联网协议的诊断通信(DoIP)-第 1 部分:一般信息和用例定义 (1/2)

如下内容基于2011版本的 ISO 13400开展,内容较多,拆分为2篇,此篇为 1/2。 前言 ISO(国际标准化组织)是一个全球范围内的国际标准机构联合体(ISO 成员机构)。国际标准的制备工作通常通过 ISO 技术委员会进行。每个相关成员机构都有权在已建立的技术委员会中代表其利益。与 ISO 保持联系的国际组织、政府和非政府组织也参与这项工作。ISO 与国际电工委员会(IEC)在所有电气

微软C#套接字异步通信代码

Asynchronous Server Socket Example.NET Framework 4 其他版本 The following example program creates a server that receives connection requests from clients. The server is built with an asynchronous socket,