# 数据通道建立 · DCEP

> 每条数据通道对应一个 SCTP 流 id，而通道怎么让两端就「叫什么、怎么配」达成一致，靠 DCEP（RFC 8832）的 DATA_CHANNEL_OPEN / ACK 握手。这一章讲清数据通道到流的映射、DCEP 带内协商，以及它与 SDP negotiated 模式的取舍。收尾第 8 部分。

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

# 数据通道建立 · DCEP

第 8 部分收尾。[上一章](https://daiw.org/manual/webrtc/sctp-streams)讲清了 SCTP 的**流**，这一章补上最后一块：一条[数据通道](https://daiw.org/manual/webrtc/data-channel-controller)怎么和流对应起来、又怎么协商开启。这两块把「[数据通道 API](https://daiw.org/manual/webrtc/data-channel-controller)」和「[SCTP 协议](https://daiw.org/manual/webrtc/dcsctp-intro)」最终接上。

## 数据通道 ⟷ SCTP 流

数据通道和 SCTP 流的映射关系：

- **每条[数据通道](https://daiw.org/manual/webrtc/data-channel-controller) = 一个 SCTP 流 id**（收发用同一个 stream id）。你 `createDataChannel` 开一条通道，就占用一个流 id。
- [`DataChannelController`](https://daiw.org/manual/webrtc/data-channel-controller) 管理“哪个流 id 对应哪条数据通道”（呼应它[靠 stream id 区分通道](https://daiw.org/manual/webrtc/data-channel-controller)的说法）。
- 数据通道的[可靠性 / 有序性配置](https://daiw.org/manual/webrtc/sctp-partial-reliability)，就落到这条流的 [SCTP 参数](https://daiw.org/manual/webrtc/sctp-partial-reliability)上（`maxRetransmits` 等）。

于是“[应用层的数据通道](https://daiw.org/manual/webrtc/data-channel-controller)”和“[传输层的 SCTP 流](https://daiw.org/manual/webrtc/sctp-streams)”一一对应，数据通道的语义（可靠？有序？）直接翻译成流的 SCTP 行为。

## DCEP：数据通道怎么开启

一条数据通道怎么让**两端都知道它开了、参数是什么**？靠 **DCEP(Data Channel Establishment Protocol,RFC 8832)**:

<Callout type="info">
  **DCEP 是一个跑在 [SCTP 流](https://daiw.org/manual/webrtc/sctp-streams)之上的小协议：开数据通道的一方，在对应流上发一个 **DATA_CHANNEL_OPEN** 消息（带上通道的标签、[可靠性 / 有序性参数](https://daiw.org/manual/webrtc/sctp-partial-reliability)、优先级），对方回一个 **DATA_CHANNEL_ACK** 确认——通道就开好了。** 于是双方对“这条流承载的数据通道叫什么、怎么配”达成一致。这和 [SDP 协商媒体](https://daiw.org/manual/webrtc/media-session)、[SCTP 握手协商参数](https://daiw.org/manual/webrtc/sctp-association)是同一层逻辑——**用一次小小的握手，让双方对一个新通道的规则对齐**。

  DCEP 消息本身就是[普通的 SCTP DATA](https://daiw.org/manual/webrtc/sctp-chunks-packets)（在特定流上、带特定标识），所以它复用了 [SCTP 的可靠传输](https://daiw.org/manual/webrtc/sctp-reliability)。注意：数据通道的**存在**也可以直接[在 SDP 里协商](https://daiw.org/manual/webrtc/sdp-and-jsep)（negotiated 模式，不用 DCEP），但常见的是用 DCEP **带内**协商（in-band，应用调 `createDataChannel` 就自动 DCEP 握手），更灵活——随时能开新通道，不必[重新协商 SDP](https://daiw.org/manual/webrtc/offer-answer-handler)。
</Callout>

## 小结与第 8 部分回顾

**每条数据通道 = 一个 [SCTP 流](https://daiw.org/manual/webrtc/sctp-streams) id**（收发同号），[`DataChannelController`](https://daiw.org/manual/webrtc/data-channel-controller) 维护这张映射表，通道的[可靠性 / 有序性配置](https://daiw.org/manual/webrtc/sctp-partial-reliability)直接落成该流的 SCTP 参数。通道开启靠 **DCEP**（`DATA_CHANNEL_OPEN` / `ACK`，带内协商通道标签与参数），消息本身就是[普通 SCTP DATA](https://daiw.org/manual/webrtc/sctp-chunks-packets)，因此复用了 [SCTP 的可靠传输](https://daiw.org/manual/webrtc/sctp-reliability)。也可以走 SDP 的 negotiated 模式跳过 DCEP，但带内协商更灵活——随时开新通道，不必[重协商 SDP](https://daiw.org/manual/webrtc/offer-answer-handler)。

**第 8 部分「数据通道与 SCTP」到此完整**：[总览](https://daiw.org/manual/webrtc/data-channel-overview) → [dcSCTP sans-IO](https://daiw.org/manual/webrtc/dcsctp-intro) → [association 握手](https://daiw.org/manual/webrtc/sctp-association) → [包与 chunk](https://daiw.org/manual/webrtc/sctp-chunks-packets) → [可靠传输](https://daiw.org/manual/webrtc/sctp-reliability) → [部分可靠](https://daiw.org/manual/webrtc/sctp-partial-reliability) → [流控拥塞](https://daiw.org/manual/webrtc/sctp-flow-congestion) → [多流](https://daiw.org/manual/webrtc/sctp-streams) → DCEP。数据通道从 API 到底层 SCTP 协议，已经拆透。

三种媒体（音、视频、数据）都讲完了。接下来退后一步，看**统管全局的 `Call` 对象和媒体引擎**——它们怎么把这一切编排起来。第 9 部分。👉 第 9 部分即将展开。

## 参考资料

- [1] libwebrtc 源码.`net/dcsctp/`（流管理）、`pc/sctp_data_channel.cc`（DCEP）、`pc/sctp_utils.cc`。
- [2] IETF RFC 8831「WebRTC Data Channels」、RFC 8832「DCEP」、RFC 9260「SCTP 多流」。
- [3] 关联[DataChannelController](https://daiw.org/manual/webrtc/data-channel-controller)。
