# SCTP 部分可靠 · 可靠性可调的杀手锏

> 数据通道能设「最多重传 3 次」或「50ms 内才重传」——这种介于 TCP 和 UDP 之间的部分可靠，是 SCTP 相对两者的杀手锏。这一章读 RFC 3758，讲清部分可靠怎么实现、FORWARD-TSN 如何跳过放弃的数据，以及它对应数据通道的哪些配置。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/webrtc/sctp-partial-reliability
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# SCTP 部分可靠 · 可靠性可调的杀手锏

[SCTP 默认可靠有序](https://daiw.org/manual/webrtc/sctp-reliability)，但[数据通道那章](https://daiw.org/manual/webrtc/data-channel-controller)说过，它的可靠性**可调**——能设成“最多重传 3 次”或“50ms 内才重传”。这种介于 [TCP（必达）和 UDP（尽力）](https://daiw.org/manual/webrtc/data-channel-overview)之间的**部分可靠（partial reliability）**，是 SCTP 独有的杀手锏（RFC 3758）。这一章看它怎么实现。

## 为什么要“部分”可靠

<Callout type="info">
  **有些数据“过期作废”——[实时游戏的玩家位置](https://daiw.org/manual/webrtc/data-channel-controller)、视频会议的某些控制信令，**旧的丢了不该重传**（重传回来时它已经被更新的取代了，浪费带宽还添延迟）。部分可靠让你说“这条数据，重传几次 / 多久内还有效，过了就放弃”。** 想象传玩家坐标，每 50ms 一次：如果第 1 帧的坐标丢了，你**根本不想重传**它——因为第 2、3 帧的新坐标早就来了，重传旧坐标毫无意义。[TCP 却会死磕](https://daiw.org/manual/webrtc/data-channel-overview)着重传那个旧坐标、还[队头阻塞](https://daiw.org/manual/webrtc/data-channel-overview)后面的新坐标——对实时数据是灾难。

  部分可靠给了**精确的中间档**：
  - **`maxRetransmits`** —— 最多重传 N 次，还没成功就放弃（N=0 就是“尽力而为”，像 [UDP](https://daiw.org/manual/webrtc/data-channel-overview)）。
  - **`maxPacketLifeTime`** —— 数据在 T 毫秒内才值得重传，超时就放弃。

  这两个旋钮（[映射自数据通道的配置](https://daiw.org/manual/webrtc/data-channel-controller)），让你**按数据的时效性精确选择可靠程度**——传文件用完全可靠、传实时位置用不可靠、传偶尔重要的用“重传几次”。**一条 association 里，不同[流](https://daiw.org/manual/webrtc/sctp-streams)可以有不同的可靠性设置**，各取所需。
</Callout>

## FORWARD-TSN：告诉对方“这块我不发了”

部分可靠有个技术难点：发送方**放弃**了某个 [TSN](https://daiw.org/manual/webrtc/sctp-reliability)（不再重传），可接收方还在**等**这个 TSN（[有序交付](https://daiw.org/manual/webrtc/sctp-reliability)要求按序，它等着这个号来才能往下交）——岂不[死锁](https://daiw.org/manual/webrtc/sctp-reliability)？解决它的是 **FORWARD-TSN chunk**:

<Callout type="info">
  **发送方放弃某些 [TSN](https://daiw.org/manual/webrtc/sctp-reliability) 后，发一个 **FORWARD-TSN** 告诉接收方“这些 TSN 我不发了，你别等了，把累积确认点往前移”——接收方于是**跳过**这些放弃的块，继续处理后面的。** 这就解开了死锁：没有 FORWARD-TSN，接收方会永远等那个[被放弃的 TSN](https://daiw.org/manual/webrtc/sctp-reliability)，后面的数据全卡住；有了它，接收方知道“这几个号作废了”，[累积点](https://daiw.org/manual/webrtc/sctp-reliability)前移，数据流继续。

  FORWARD-TSN 是部分可靠的**关键机制**——它让“放弃某些数据”这件事，能被双方**一致地**处理，不至于一方放弃、另一方傻等。dcSCTP 的 `net/dcsctp/tx/` 在放弃块时生成 FORWARD-TSN，`rx/` 处理它并前移接收窗口。这个“显式告知放弃、让对方跳过”的设计，是“[优雅地丢弃](https://daiw.org/manual/webrtc/video-decode-recovery)”在传输层的体现：不是悄悄不发（那会卡死对方），而是**明确协商放弃**。
</Callout>

## 一张对比：TCP / SCTP-PR / UDP

部分可靠让 SCTP 覆盖了从 TCP 到 UDP 的**整个可靠性谱系**：

| | TCP | SCTP 部分可靠 | UDP |
| --- | --- | --- | --- |
| 可靠性 | 完全可靠 | **可调**（重传次数 / 时限） | 不可靠 |
| 有序性 | 强制有序 | **可选**（有序 / 无序） | 无序 |
| 队头阻塞 | 有 | [多流无阻塞](https://daiw.org/manual/webrtc/sctp-streams) | 无 |
| 适合 | 文件 | **实时 + 可靠混合** | 纯实时 |

<Callout type="info">
  **SCTP 部分可靠的价值，是**一个协议覆盖整个谱系**——你不必在“TCP 太死板”和“UDP 太原始”之间二选一，而能**为每种数据精确调档**。** 一次通话里：传文件的[数据通道](https://daiw.org/manual/webrtc/data-channel-controller)用完全可靠有序（像 TCP）、传实时光标的用不可靠无序（像 UDP）、传偶尔重要状态的用“重传 2 次”（中间档）——**它们复用[同一个 association](https://daiw.org/manual/webrtc/sctp-association)、同一条[加密通路](https://daiw.org/manual/webrtc/dtls-handshake)，各按自己的时效性选可靠度**。这种灵活，是 [TCP/UDP 都给不了的](https://daiw.org/manual/webrtc/data-channel-overview)，也是 WebRTC [数据通道能力](https://daiw.org/manual/webrtc/data-channel-controller)的根基。
</Callout>

## 小结与下一章

**部分可靠**（RFC 3758）是 SCTP 的杀手锏——让可靠性在 [TCP 和 UDP 之间可调](https://daiw.org/manual/webrtc/data-channel-overview)：**`maxRetransmits`**（最多重传 N 次）/ **`maxPacketLifeTime`**（T 毫秒内才重传），按数据**时效性**选档（[实时数据旧的丢了不重传](https://daiw.org/manual/webrtc/data-channel-controller)）。难点是放弃 [TSN](https://daiw.org/manual/webrtc/sctp-reliability) 后接收方别傻等——**FORWARD-TSN** 告知放弃、让对方**跳过**、前移累积点，解开死锁。一条 association 里[不同流可有不同可靠性](https://daiw.org/manual/webrtc/sctp-streams)，一个协议覆盖从 TCP 到 UDP 的整个谱系。

可靠性讲完，还有“发多快”的问题——SCTP 也有流控和拥塞控制。下一章。👉 [SCTP 流控与拥塞控制](https://daiw.org/manual/webrtc/sctp-flow-congestion)。

## 参考资料

- [1] libwebrtc 源码.`net/dcsctp/tx/`（放弃块、FORWARD-TSN 生成）、`net/dcsctp/packet/chunk/forward_tsn_chunk.h`。
- [2] IETF RFC 3758「SCTP Partial Reliability Extension （PR-SCTP）」、RFC 8831（数据通道可靠性映射）。
- [3] 关联[数据通道可靠性配置](https://daiw.org/manual/webrtc/data-channel-controller)。
