📚 第六章 TCP与UDP
📄 一句话概括

DCCP 要的是「不可靠,但会看路况」:有连接、有拥塞控制,但丢了不重传。 它的定位很尴尬:UDP 不需要它,TCP 又太可靠,最后只能活在少数场景。

📝 本节和前面几节的关系

6.5.2 的 SCTP 是「全都要」,DCCP 是「只要拥塞控制」。 6.4.9 讲的是 TCP 的拥塞控制,DCCP 把它单独拆了出来。

一、它补的是 UDP 的「不礼貌」

UDP 的问题不是「不安全」,是「不礼貌」: 它不管链路堵不堵,照样按自己的码率发,把别人的包挤掉。 所以「整个网络都跑 UDP」会互相伤害。 DCCP 的想法是「保留 UDP 的低延迟,补上拥塞控制」: 它建连接、有确认、会减速,但「丢了不重传」。 确认只用来「测路况」,不用来「补数据」。 这个定位很清晰:它就是「有礼貌的 UDP」。 可惜「有礼貌」这件事,应用自己也能做——WebRTC 就在 UDP 上自己实现了一套拥塞控制。

二、四种协议的定位

协议 可靠 拥塞控制 典型用途
TCP 是 是 网页、文件
UDP 否 否 语音、游戏
DCCP 否 是 流媒体
SCTP 是 是 信令

四行其实是「两个维度」的组合:「要不要可靠」和「要不要礼貌」。 TCP 两个都要,UDP 两个都不要,后两个各要一半。 这张表最该记住的是「没有一格是空的」:每个组合都有人做过, 说明「取舍的空间」是被穷举过的——只是最后活下来的只有两个。

三、为什么它也没起来

第一是「中间设备不认」:协议号 33,和 SCTP 一样卡在这一关。 而流媒体这件事,实际上用「UDP 加应用层拥塞控制」就解决了。 第二是「它解决的是一个不那么痛的问题」: 「UDP 不礼貌」在「自己的网内」不痛——因为流量是自己管的。 只有「跨运营商、大规模」才痛,而那种场合,改协议的成本远高于「在应用层做」。 所以这三个协议(UDP-Lite、SCTP、DCCP)的结局是一样的:设计上都有道理,部署上都没起来。 它们的价值不在「用」,而在「知道取舍的边界在哪」。

四、动手 Demo:DCCP,不可靠但讲礼貌

把四个协议按「可靠」和「有拥塞控制」两个维度摆开。 看第四行之外那三行,就知道取舍空间被穷举过了。

rows = (('TCP', '是', '是'), ('UDP', '否', '否'),
        ('DCCP', '否', '是'), ('SCTP', '是', '是'))
for name, rel, cc in rows:
    print('%-6s 可靠 %s  拥塞控制 %s' % (name, rel, cc))

实跑输出:

--------------------------------------------------------------------
DCCP,不可靠但讲礼貌
--------------------------------------------------------------------
**DCCP 的位置很尴尬**:**UDP 没有拥塞控制,TCP 又必须可靠。**它要的是「不可靠,但会看路况」。**

  协议         可靠       拥塞控制     典型用途
  ----------------------------------------------------
  **TCP**      **是**     **是**       **网页、文件**
  **UDP**      **否**     **否**       **语音、游戏**
  **DCCP**     **否**     **是**       **流媒体**
  **SCTP**     **是**     **是**       **信令**

**第二行的问题不是「不安全」,是「不礼貌」**:**UDP 应用不管链路堵不堵,照样按自己的码率发**,
**把别人的包挤掉。**
**所以「整个网络都跑 UDP」会互相伤害**——
**这也是为什么浏览器里的实时音视频要用「拥塞控制版的 UDP」**
**(WebRTC 自己实现了一套)。**

**第三行想「在协议层把礼貌补上」**:**有连接、有确认、有拥塞控制,**但「丢了不重传」。**
**它的确认只用来「测路况」,不用来「补数据」。**
**这个思路很干净**,**问题是「中间设备不认」加「应用已经自己做了」**,
**所以部署量极小**——和 SCTP 一样,属于「知道有这回事」就够的协议。

DCCP 那行「否 是」是它唯一的卖点:「丢了不重传」保证低延迟,「有拥塞控制」保证不害人。 理论上这是流媒体的最优解。 但「理论最优」不等于「实际会用」:因为「应用层自己做」的成本更低,而且不用求任何人支持。 WebRTC 就是活例子——它在 UDP 上把该做的都做了。 最后一个观察:这三个协议都是「上世纪九十年代到本世纪初」的产物, 那个年代「改操作系统」比现在容易,但「改中间设备」同样难。 所以「卡在部署」这个结局,从设计那天就注定了。

30 秒实验

  1. 想一下:DCCP 的确认和 TCP 的确认有什么不同用途?
  2. 想一下:为什么「UDP 不礼貌」在自己的网内不痛?
  3. 想一下:三个「没起来」的协议有什么共同点?

常见误区

  1. 以为「DCCP 是 UDP 加可靠」。 它故意不可靠,只是加了拥塞控制。
  2. 以为「有拥塞控制就必须重传」。 两件事独立,DCCP 就是「只减速不重传」。
  3. 以为「设计好就会普及」。 部署取决于中间设备,这三个协议全卡在这一关。
自测三问(点开对答案) 1. DCCP 的定位是什么? —— **不可靠但有拥塞控制**,也就是「有礼貌的 UDP」。 2. DCCP 的确认用来做什么? —— **只用来测路况**,不用来触发重传。 3. 为什么它和 SCTP 都没普及? —— **中间设备不认**,而它们想解决的问题在应用层也能做。

下一节开始拆首部:先看只有 8 字节的 UDP。

相关笔记