65.9K
CodeProject 正在变化。 阅读更多。
Home

Java, C# 和 VB 开发人员的 SDP 入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (8投票s)

2010 年 7 月 30 日

CPOL

8分钟阅读

viewsIcon

42080

本文档旨在为希望快速了解协议工作原理和细节的 Java、C# 和 VB 程序员提供关于会话描述协议 (Session Description Protocol) 的技术概述。

会话描述协议 (SDP)

随着用于协商和定义通信会话参数的协议(例如会话发起协议)的出现,需要解释其目的和注册过程。会话描述协议 (SDP),在 RFC4566 中定义,通过提供会话特征和媒体定义的格式来实现这一点。作为会话协商的一部分,各方应就描述值、时序、各自的能力和所需的媒体格式达成一致。这种交换被称为“提问/应答模型”(Offer/Answer Model),并在 RFC3264 中正式化。SDP 可与多种传输协议一起使用,例如会话公告协议 (SAP)、会话发起协议 (SIP)、超文本传输协议 (HTTP) 等。

目录

SDP 消息中必须包含几个重要信息

  • 会话名称。
  • 会话的活动时间。
  • 组成会话的媒体。
  • 会话的所有者/发起者。
  • 如何接收媒体(地址、端口等)。

还可以提供其他可选信息

  • 会议将使用的带宽。
  • 会话的目的。
  • 负责人的联系信息。
  • 时区信息。
  • 扩展 SDP 的会话属性。

该协议的编码主要是 UTF8(描述性字段可以有其他编码,如“charset”属性指定 - 稍后定义)。每个信息都包含在一个字段中。每个字段都通过回车/换行符序列 [CRLF] 分隔。每个字段的格式为

<type> = <value>

其中 <type> 是一个不区分大小写且唯一的单字符字段名,<value> 是结构化文本,其格式取决于 <type>。它们由一个无填充的“=”(等号)分隔。

消息结构

SDP 消息包含三个主要部分,分别详细说明会话、时序和媒体描述。每条消息可能包含多个时序和媒体描述。每个字段必须按所示顺序出现。

会话描述

表 4 对消息进行了细分,并更详细地描述了每个部分。

表 1. 会话描述
字段 类型 选项/必需 描述
协议版本 v M 当前协议版本。根据 RFC4566,始终为“0”。
Origin o M 会话发起者的名称和会话标识符。
会话名称 s M 文本形式的会话名称。
会话信息 i O 关于会话的文本信息。
URI u O 指向补充会话信息的指针。
电子邮件地址 e O 负责人的电子邮件联系信息。
电话号码 p O 负责人的电话联系信息。
连接数据 c C 连接类型和地址。
带宽 b C 提议的带宽限制。
时序描述在此处
时区 z O 考虑夏令时信息。
加密密钥 K O 用于交换密钥的简单机制。很少使用。
属性 A O 一个或多个扩展协议的属性。
媒体描述在此处

注意:M - 必需;O - 可选;C - 条件(连接数据必须出现在会话或媒体描述中)。

时序描述

表 2. 时序描述
字段 类型 选项/必需 描述
时序 t M 开始和结束时间。
重复时间 r O 指定任何会话重复的持续时间和间隔。

时间表示为网络协议时间 (RFC1305):自 1900 年以来的秒数;间隔可以用 NTP 时间或类型化时间表示:一个值和时间单位(天 ('d')、小时 ('h')、分钟 ('m') 和秒 ('s'))序列。

因此,2010 年 8 月 1 日上午 10 点开始的一个小时会议,并在同一时间点一周后重复一次,可以表示为

t=3487140000 3487143600
r=604800 3600 0

或使用类型化时间

t=3487140000 3487143600
r=7d 3600 0

媒体描述

表 3. 媒体描述
字段 类型 选项/必需 描述
媒体描述 m M 媒体定义,包括媒体类型(例如,“audio”)、传输详细信息和格式。
会话信息 与上面相同
连接数据 与上面相同
带宽 与上面相同
加密密钥 与上面相同
属性 与上面相同

属性

SDP 使用属性来扩展核心协议。属性可以出现在会话或媒体部分,并相应地划分为“会话级”或“媒体级”。

属性有两种形式

  • 属性形式:“a=<flag>”传达会话的属性。
  • 值形式:“a=<attribute>:<value>”提供一个命名参数。

表 4. 示例属性
Attribute 表单 描述
类别 cat:<category> 用于过滤会话的点分隔的层级类别。
关键词 keywds:<keywords> 有助于识别会话。
RTP 有效载荷类型 rtpmap:<payload type> <encoding name>/<clock rate> 将 RTP 有效载荷映射到编码、格式和时钟速率。
仅接收 recvonly 工具应以仅接收模式启动。
发送/接收 sendrecv 工具可以以发送和接收模式启动。
类型 type:<conference type> 类型包括“broadcast”(广播)、“meeting”(会议)和“moderated”(受控)。
字符集 charset:<character set> 会话名称和信息字段中使用的字符集。
语言 lang:<language tag> 会话的默认语言。

示例

以下是一个关于“SDP 实现”的研讨会演示的示例会话描述,该演示可通过 RTP 以音频和视频形式在地址 100.101.102.103 上可用,端口分别为 49170 和 51372。这是一个小时的研讨会,将于 2010 年 8 月 1 日上午 10 点开始,联系人是 John Doe,电子邮件为 jdoe@arrhus.com。

注意:所有代码示例在语言上都是无关紧要的。对于那些有兴趣进一步探索 SDP 的人,我们提供了推荐的 Java、.NET 和 C++ API 列表。 并且所有代码都应该能与其中任何一个配合使用,只需少量注释(我碰巧在此案例中使用了 Konnetic 的 SIP C# API)。

注意:Alice 调用 Bob 是 SDP 的原型“Hello World”应用程序的等价物。

  1. 创建 SDP 消息或结构。对于 RFC4566,协议版本为“0”。
  2. SdpMessage sdp = new SdpMessage();
  3. 添加 Origin 字段,包含唯一的会话 ID、版本、发起者的姓名和地址——地址可以是 IP 地址或完全限定域名 (FQDN)。在此示例中,jdoe 是发起者。会话 ID 为 2890844526,版本为 89。会话是在机器 214.191.7.5 上创建的。
  4. sdp.Origin.UserName = "jdoe";
    sdp.Origin.SessionId = 2890844526;
    sdp.Origin.SessionVersion = 89; 
    sdp.Origin.Address = new IPHost("214.191.7.5");
  5. 添加会话名称和信息,包括指向包含更多信息的网站的链接。
  6. sdp.SessionName = "SDP Implementation";
    sdp.SessionInformation = "A Seminar on the session description protocol";
    sdp.Uri = new Uri("http://www.arrhussdp.com/documents/sdpseminar.html");
  7. 添加负责人的联系信息。这是 John Doe 的电子邮件,包含全名。
  8. sdp.Emails.Add(new EmailHeaderField("jdoe@arrhus.com", "John Doe"));
  9. 添加有关如何接收会话的连接信息。地址可以是 IP 地址或完全限定域名 (FQDN)。在此示例中,使用了到会话主机的 IP 连接。
  10. sdp.Connection.Address = new IPHost("100.101.102.103");
  11. 添加时序。至少有一个时间字段,也可以有多个。一个好的 API 会允许您提供 NTP 时间或 DateTime。时间的输出将始终是自 1900 年以来的秒数(分别为 3487140000 和 3487143600)。这些时间表示 2010 年 8 月 1 日上午 10 点开始的一个小时会议。
  12. TimeDescriptionHeaderField td = new TimeDescriptionHeaderField();
    td.Timings.Start = new SdpTime(new DateTime(2010, 7, 1, 10, 0, 0, 0));
    td.Timings.Stop = new SdpTime(new DateTime(2010, 7, 1, 11, 0, 0, 0));
    sdp.TimeDescriptions.Add(td);
  13. 现在,我们可以为会话添加属性。此属性作用域为会话,并指示应用程序应以仅接收模式启动会话。
  14. sdp.Attributes.Add(new AttributeHeaderField("recvonly"));
  15. 在此示例中,我们添加了两个媒体描述部分。第一个是音频,端口为 49170,使用最小控制的 RTP 配置文件,运行在 UDP 之上。最后一个零是 RTP/AVP 的额外参数信息。
  16. MediaHeaderField mh = new MediaHeaderField(SdpMedia.Audio,49172,
                          SdpMediaProtocol.RtpAvp,"0"); 
    sdp.MediaDescriptions.Add(new MediaDescriptionHeaderField(mh));
  17. 第二个媒体描述是视频,端口为 51372,使用最小控制的 RTP 配置文件,运行在 UDP 之上。最后的 31 是 RTP/AVP 的额外参数信息。此属性作用域为媒体描述。任何演示都将以纵向显示。
  18. MediaHeaderField mh1 = new MediaHeaderField(SdpMedia.Video, 51372, 
                           SdpMediaProtocol.RtpAvp, "31");
    MediaDescriptionHeaderField md = new MediaDescriptionHeaderField(mh1);
    md.Attributes.Add(new AttributeHeaderField("orient", "portrait"));
    sdp.MediaDescriptions.Add(md);

    注意:两个媒体描述(以 m 开头的行)定义了音频和视频配置文件。这些配置文件在实时传输协议 (RTP) 规范 RFC3550 及其配套的最小控制 RTP 音视频会议配置文件 RFC3551 中有描述。

SDP 消息

最终的 SDP 消息应与以下内容完全一致

v=0
o=jdoe 2890844526 89 IN IP4 214.191.7.5
s=SDP Implementation
i=A Seminar on the session description protocol
u=http://www.arrhussdp.com/documents/sdpseminar.html
e=jdoe@arrhus.com (John Doe)
c=IN IP4 100.101.102.103
t=3487140000 3487143600
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 31
a=orient:portrait

SDP 库和 API

通常,SDP API 是在 SIP 库中实现的,因此此列表与推荐的 SIP 库相吻合。它并非详尽无遗;它们只是我遇到的最好的。一个好的 SDP API 的明智标准是它是否支持强类型字段、合理地实现了时序,并提供了许多有用的枚举。

表 5. 推荐的 SIP 栈
语言 链接 描述
Java NIST 的 SIP 库 美国国家标准与技术研究院的参考 API。
C#, VB 等。 Konnetic 的 SIP .NET 库 文档齐全的低级 SIP 和 SDP 栈。
C#, VB 等。 Microsoft 的统一通信服务器 高级 SIP、SDP 和 RTP 栈。
C++ PJSIP SIP 栈 轻量级但功能齐全且高度可移植的 SIP 栈。

测试工具

测试工具至关重要,因为任何与 SIP 应用程序和服务器交互的应用程序都必须遵守标准。

表 6. 推荐的 SIP 测试工具
工具 描述
SIPp 惠普的 SIP 流量生成器。
PROTOS 来自芬兰奥卢大学的测试应用程序。
ETSI TS 102 027-2 SIP 测试呼叫流程列表。

延伸阅读

相关文章

© . All rights reserved.