为好奇的人提供的 WebRTC|07 数据通信

本系列文章跳转目录如下:

  1. 是什么,为什么,如何使用
  2. 信令(交换信令消息后,WebRTC Agent才可以直接相互通信。)
  3. 连接( 为什么WebRTC需要专用的子系统进行连接,又是怎样连接的?)
  4. 安全性( WebRTC具有哪些安全性保障,又是如何做到的?)
  5. 搭建实时网络(网络在实时通信中的重要性以及如何处理网络中的各种问题)
  6. 媒体通信(WebRTC媒体通信的作用及其工作原理)
  7. 数据通信(WebRTC数据通信的作用及其工作原理)
  8. WebRTC应用场景(人们使用WebRTC构建什么以及他们是如何实现的)
  9. 调试(如何分析并定位相关问题,以及一些流行的调试工具)
  10. 历史(对WebRTC一系列协议作者的采访)
  11. 常见问题( 使用WebRTC时常见的问题及解答)
  12. 术语

我可以从WebRTC的数据通信中获得什么?

WebRTC提供用于数据通信的数据通道。在两个peer之间,你可以打开65,534个数据通道。
数据通道基于数据报,并且每个通道都有其自己的持久性设置。默认设置下,每个数据通道都能保证有序交付。

如果你从传递媒体数据的角度开始接触WebRTC,可能数据通道看起来是一种浪费。当我只使用HTTP或WebSocket就能传递数据的时候,为什么需要整个数据通道子系统呢?

数据通道的真正强大之处在于,你可以将它们配置为像UDP一样进行无序/有损传递。
对于低延迟和高性能的情况,这是必需的。你可以测量背压,并确保你仅发送网络支持的最大数据量。

它是如何工作的?

WebRTC使用RFC 2960中定义的流控制传输协议(SCTP)。SCTP是一种传输层协议,旨在替代TCP或UDP。对于WebRTC,我们将SCTP用作在DTLS连接上运行的应用层协议。

SCTP为你提供流,并且每个流都可以独立配置。WebRTC数据通道只是基于流的简单抽象。有关持久性和顺序的设置会被直接传递到SCTP Agent中。

数据通道具有SCTP无法表达的某些功能,例如通道标签。为了解决该问题,WebRTC使用了RFC 8832中定义的数据通道建立协议(DCEP)。DCEP定义了一条消息,用于传递通道标签和协议。

DCEP

DCEP只有两个消息DATA_CHANNEL_OPENDATA_CHANNEL_ACK。对于打开的每个数据通道,远端必须以ack响应。

DATA_CHANNEL_OPEN

该消息由希望打开数据通道的WebRTC Agent发送。

封包格式

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Message Type |  Channel Type |            Priority           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Reliability Parameter                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Label Length          |       Protocol Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                             Label                             /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                            Protocol                           /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

消息类型(Message Type)

消息类型是一个静态值0x03

通道类型(Channel Type)

Channel Type controls durability/ordering attributes of the channel. It may have the following values:
通道类型控制通道的持久性/排序属性。它可能具有以下值:

  • DATA_CHANNEL_RELIABLE (0x00) - 没有消息丢失,消息依序到达。
  • DATA_CHANNEL_RELIABLE_UNORDERED (0x80) - 没有消息丢失,但消息可能乱序到达。
  • DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT (0x01) - 按照请求中的次数重试发送后,消息可能会丢失,但消息将依序到达。
  • DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED (0x81) - 按照请求中的次数重试发送后,消息可能会丢失,且消息可能乱序到达。
  • DATA_CHANNEL_PARTIAL_RELIABLE_TIMED (0x02) - 如果没有在请求的时间内到达,消息可能会丢失,但消息将依序到达。
  • DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED (0x82) - 如果没有在请求的时间内到达,消息可能会丢失,且消息可能乱序到达。

优先级(Priority)

数据通道的优先级。具有较高优先级的数据通道将首先被调度。较大的低优先级用户消息不会耽误高优先级用户消息的发送。

可靠性参数

如果数据通道类型的前缀为DATA_CHANNEL_PARTIAL_RELIABLE,则不同的后缀对应的参数配置如下:

  • REXMIT - 定义发送方重试发送消息的次数,超出此次数将放弃尝试。
  • TIMED - 定义发送方重试发送消息的时间(以毫秒为单位),超出此时间将放弃尝试。

标签(Label)

一个包含数据通道名称的UTF-8编码的字符串。可能为空。

协议(Protocol)

如果这里为空字符串,则协议未指定。如果是非空字符串,则这里应指定一个协议,可指定的协议请参考RFC 6455中定义的"WebSocket子协议名称注册表"中的注册协议。

DATA_CHANNEL_ACK

WebRTC Agent发送此消息以确认此数据通道已打开。

封包格式

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Message Type |
+-+-+-+-+-+-+-+-+

流控传输协议(SCTP)

SCTP是WebRTC数据通道背后的真正动力。它提供了数据通道的以下所有功能:

  • 多路复用
  • 使用类似TCP的重传机制进行可靠传递
  • 部分可靠性选项
  • 避免拥塞
  • 流量控制

为了理解SCTP,我们将分三个部分进行探讨。我们的目标是,在本章之后,你将拥有足够的知识来自行调试和学习SCTP的详细信息。

概念

SCTP协议功能很多。本节仅涵盖WebRTC使用的SCTP部分。
SCTP中,WebRTC不使用的功能包括多宿主(multi-homing)和路径选择。

经过20多年的发展,SCTP变得难以完全掌握。

关联(Association)

关联是用于SCTP会话的术语。这是两个SCTP Agent在通信时共享的状态。

一个流是用户数据的一个双向序列。创建数据通道时,实际上只是在创建一个SCTP流。每个SCTP关联都包含一个流列表。可以为每个流配置不同的可靠性类型。

WebRTC只允许你在创建流时进行配置,而SCTP实际上允许随时更改配置。

基于数据报

SCTP将数据构造为数据报,而不是字节流。发送和接收数据就像是使用UDP而不是TCP。
你无需添加任何额外的代码即可通过一个流传输多个文件。

SCTP消息没有像UDP这样的大小限制。单个SCTP消息的大小可以达到几个GB。

块(Chunks)

SCTP协议由块组成。有许多不同类型的块。这些块用于所有通信。
用户数据,连接初始化,拥塞控制等,全部通过块完成。

每个SCTP数据包都包含一个块列表。因此,在一个UDP数据包中,你可以有多个块承载来自不同流的消息。

传输序列号

传输序列号(TSN)是DATA块的全局唯一标识符。DATA块承载用户希望发送的所有消息。TSN很重要,因为它可以帮助接收方确定数据包是否丢失或乱序。

如果接收方注意到缺少TSN,则在数据完整获取之前,它不应将数据提供给用户。

流标识符

每个流都有一个唯一的标识符。当你创建带有显式ID的数据通道时,实际上是将其作为流标识符直接传递到SCTP中。如果你没有传递ID,则会为你自动选择流标识符。

有效负载协议标识符

每个DATA块还具有一个有效负载协议标识符(PPID)。这用于唯一地标识正在交换的数据类型。
SCTP具有许多PPID,但是WebRTC仅使用以下五种:

  • WebRTC DCEP (50) - DCEP消息。
  • WebRTC String (51) - Datachannel字符串消息。
  • WebRTC Binary (53) - Datachannel二进制消息。
  • WebRTC String Empty (56) - 长度为0的Datachannel字符串消息。
  • WebRTC Binary Empty (57) - 长度为0的Datachannel二进制消息。

协议

以下是SCTP协议使用的一些块。这不是一个详尽的演示。只提供了足够的结构让状态机运作起来。

每个块均以type字段开头。在块列表之前,还有一个头字段。

DATA块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 0    | Reserved|U|B|E|    Length                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              TSN                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Stream Identifier        |   Stream Sequence Number      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Payload Protocol Identifier                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                            User Data                          /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

DATA块是交换所有用户数据的方式。下面是对DATA块更详细的说明,数据就是这样通过数据通道被发送的。

如果是无序数据包,则将U位设置为1。我们可以忽略流序列号(Stream Sequence Number)。

BE是开始位和结束位。如果要发送的消息对于单个DATA块而言太大,则需要将其分片成多个DATA块发送。
SCTP使用 比特位BE 以及序列号(TSN)来描述消息分包。

  • B=1, E=0 - 用户消息的第一个分片。
  • B=0, E=0 - 用户消息的中间的分片。
  • B=0, E=1 - 用户消息的最后一个分片。
  • B=1, E=1 - 未分片的用户消息。

TSNTransmission Sequence Number,一个 DATA chunk 的唯一标识符。它是一个递增的32-bit数,在达到最大值4,294,967,295 之后,继续从0开始递增。

Stream Identifier(流标识符)是该数据所属流的唯一标识符。

Stream Sequence Number , 标识一个用户消息。它是一个递增的16-bit数,在 达到最大值 65535 之后,继续从0开始递增。
比特位U设置为1时,表示无序消息包,Stream Sequence Number可以忽略。
比特位U设置为0时,表示有序消息包,该编号用于确定消息包的顺序。
与TSN类似,但是 Stream Sequence Number 以一个用户消息的粒度递增,TSN以一个Chunk的粒度递增。

Payload Protocol Identifier(有效负载协议标识符)是流过此流的数据类型。对于WebRTC而言,它可能是DCEP,String或Binary。

User Data(用户数据)就是你要发送的内容。通过WebRTC Data Channel发送的所有数据均通过DATA块传输。

INIT块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 1    |  Chunk Flags  |      Chunk Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Initiate Tag                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Advertised Receiver Window Credit (a_rwnd)          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Number of Outbound Streams   |  Number of Inbound Streams    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Initial TSN                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/              Optional/Variable-Length Parameters              /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

INIT块开始创建一个关联(association)的过程。

Initiate Tag(启动标签)用于生成Cookie。Cookies技术在中间人攻击和DoS保护中可能会被用到。在状态机章节中对它们进行了更详细的描述。

Advertised Receiver Window Credit(广播接收者窗口信用值)用于SCTP的拥塞控制。它传达了接收方已为此关联分配了多大的缓冲区。

Number of Outbound/Inbound Streams(出站/入站流的数量)通知该Agent支持多少个流。

Initial TSN(初始TSN)是随机的uint32,本地TSN以这个值开始计数。

Optional Parameters(可选参数)允许SCTP向协议引入新功能。

SACK块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 3    |Chunk  Flags   |      Chunk Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Cumulative TSN Ack                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Advertised Receiver Window Credit (a_rwnd)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Number of Gap Ack Blocks = N  |  Number of Duplicate TSNs = X |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Gap Ack Block #1 Start       |   Gap Ack Block #1 End        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                                                               /
\                              ...                              \
/                                                               /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Gap Ack Block #N Start      |  Gap Ack Block #N End         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Duplicate TSN 1                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                                                               /
\                              ...                              \
/                                                               /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Duplicate TSN X                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

SACK(选择性确认)块是接收方通知发送方它已收到数据包信息的方式。在发送方获得针对TSN的SACK之前,它将重新发送有问题的DATA块。然而,SACK的作用不只是更新TSN信息。

Cumulative TSN ACK(累积TSN ACK)是已收到的最高TSN。

Advertised Receiver Window Credit(广播接收者窗口信用值)是接收方的缓冲区大小。如果可用内存增加,接收方可以在会话期间更改此设置。

Cumulative TSN ACK(累积TSN ACK)后面,是Ack Blocks的TSN。
这个方法用来解决传送的数据包中有缺口的问题。假设我们收到了带有TSN100,102,103104的DATA块。Cumulative TSN ACK应该是100,但可以使用Ack Blocks来告诉发送方不需要重新发送102,103104

Duplicate TSN(重复TSN)会通知发送方,它已经不止一次的接收了哪些DATA数据块。

HEARTBEAT块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 4    | Chunk  Flags  |      Heartbeat Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/            Heartbeat Information TLV (Variable-Length)        /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

HEARTBEAT块用于断言远端仍能响应。
当你不发送任何DATA数据块,且需要保持NAT映射打开时,这很有用。

ABORT块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 6    |Reserved     |T|           Length              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                                                               /
\               Zero or more Error Causes                       \
/                                                               /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ABORT块用于关联的突然关闭。当一侧进入错误状态时使用。正常结束连接使用SHUTDOWN块。

SHUTDOWN块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 7    | Chunk  Flags  |      Length = 8               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Cumulative TSN Ack                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

SHUTDOWN块将正常关闭SCTP关联。
每个Agent将其发送的最后一个TSN通知给远端。这样可以确保不会丢失任何数据包。(如果有资源仍在使用中的话,)WebRTC不能正常关闭SCTP关联。你需要自行关闭所有数据通道。

Cumulative TSN ACK(累积TSN ACK)是发送的最后一个TSN。双方都知道在接收到此TSN对应的DATA块之前不要终止。

ERROR块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 9    | Chunk  Flags  |           Length              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                    One or more Error Causes                   /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ERROR块用于通知远端SCTP Agent:本端发生了非致命错误。

FORWARD TSN块

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 192  |  Flags = 0x00 |        Length = Variable      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      New Cumulative TSN                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Stream-1              |       Stream Sequence-1       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               /
/                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Stream-N              |       Stream Sequence-N       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

FORWARD TSN块将全局TSN向前移动。SCTP这样做是为了允许跳过一些你不再关心的数据包。假设你发送了10 11 12 13 14 15,这些数据包只有在它们全部到达后才有意义。而这些数据又对实时性很敏感,在这种情况下,如果数据收晚了,它们就没有用了。

如果你丢失了1213,则不需要再发送1415
SCTP使用FORWARD TSN块来实现这一点。它告诉接收方,1415将不再传递。

New Cumulative TSN(新的累积TSN),是连接的新TSN。此TSN之前的任何数据包都不会被保留。

Stream(流)和Stream Sequence(流序列)用于将Stream Sequence Number的编号向前跳转。请参阅前面的DATA块以了解该字段的重要性。

状态机

这里是SCTP状态机中一些有趣的部分。WebRTC并未使用SCTP状态机的所有功能,因此我们将没有用到的部分排除在外。我们还简化了一些组件,使它们更易于理解。

连接建立流程

INITINIT ACK块用于交换peer的能力和配置。SCTP在握手期间使用cookie来验证与之通信的peer。
这是为了确保握手不会被拦截并防止DoS攻击。

INIT ACK块包含cookie。然后,使用COOKIE ECHO将cookie返回给其创建者。如果cookie验证成功,则发送COOKIE ACK,并且准备交换DATA块。

连接关闭流程

SCTP使用SHUTDOWN块。当Agent收到SHUTDOWN块时,它将等待直到收到请求的Cumulative TSN ACK。这样,即使连接有损,用户也可以确保传送了所有数据。

Keep-Alive(保持活动)机制

SCTP使用HEARTBEAT REQUESTHEARTBEAT ACK块使连接保持活动状态。它们以固定间隔发送,间隔时间可配置。如果数据包尚未到达,SCTP还会将指数回退。

HEARTBEAT块还包含一个时间值。两个关联可以用此来计算两个Agent之间的数据传递时间。

原文地址:Data Communication | WebRTC for the Curious