Skip to content

第一百一十九章:UDP 之道

问道期

涉及内核源码:

林小源离开 TCP 的领地,来到了一片截然不同的海域。

这里没有航道,没有灯塔,没有舵手。海面上漂浮着无数小船,每艘船上都装着一个数据包,随意地朝四面八方驶去。有的到达了目的地,有的沉入海底,有的被风吹偏了方向——没有人在意。

"这也太乱了。"林小源皱眉。

"乱?"一个爽朗的笑声从旁边传来,"这叫自由。"

林小源转头,看到一个穿着短衫的年轻人坐在码头边,双脚悬在水面上,随意地踢着浪花。他的衣服上没有任何复杂的花纹——只有一个简单的八字头,比 TCP 的头小得多。

"我是 UDP。"年轻人说,"User Datagram Protocol。你看到的这些小船——每艘都是一个数据报。我只管把它们扔出去,不管它们到不到。"

"那到了怎么办?"

"那是应用程序的事。"UDP 笑着说,"我不握手,不确认,不重传,不排序。你给我数据,我加上 8 字节的头——源端口、目的端口、长度、校验和——然后扔出去。简单。"

林小源看着那些随意漂流的小船:"那不是很容易丢包?"

"是啊。"UDP 一点也不在意,"但你想想——DNS 查询,一个请求一个响应,需要三次握手吗?视频直播,丢了几个包,需要重传吗?游戏里实时的位置更新,等得起超时吗?"

"你是说……有时候不需要可靠性?"

"不是不需要——是不需要我来做。"UDP 站起身,"应用程序自己决定要不要可靠性。要的话,它自己在应用层实现;不要的话,就享受我的速度。"

林小源注意到码头的另一端有一座巨大的造船厂,里面的工人们正在建造一种奇特的船——外表是 UDP 的小船,但内部结构复杂得多,有确认系统、有重传机制、有加密模块。

"那是什么?"

"QUIC。"UDP 的眼神变得认真起来,"Google 的杰作。它用 UDP 的船身,装上了 TCP 的内核——在应用层实现了可靠传输。"

"那为什么不直接用 TCP?"

"因为 TCP 太慢了。"UDP 说,"TCP 的握手和 TLS 的握手要两个 RTT。QUIC 把它们合在一起,0-RTT 或 1-RTT 就能建立连接。而且 TCP 的实现在内核里,更新要重启系统;QUIC 的实现在用户空间,更新应用程序就行。"

"HTTP/3 就是用 QUIC?"

"对。"UDP 指向造船厂里一艘完工的船,上面刻着 HTTP/3 的标记,"QUIC 是 HTTP/3 的基础。它内置了 TLS 加密,支持多路复用——一个连接上可以同时传多个流,互不干扰。TCP 的队头阻塞问题,在 QUIC 里不存在。"

林小源看着那艘船,忽然明白了——UDP 不是"不可靠",而是"自由"。它把选择权交给应用程序,让应用程序根据自己的需求决定怎么做。

"你知道端到端原则吗?"UDP 问。

林小源摇头。

UDP 指了指大海:"网络设计的端到端原则——可靠性等功能应该在端点实现,而不是在网络中间。"

"为什么?"

"因为网络中间的节点不知道端点需要什么。"UDP 说,"路由器只负责转发数据包,它不知道这个包是 DNS 查询还是视频流,不知道它需要可靠传输还是低延迟。如果网络中间做了可靠性保证,对不需要可靠性的应用来说就是浪费。"

"所以你把控制权交给端点?"

"对。"UDP 说,"我只负责传输——从 A 到 B,尽最大努力。要可靠性,端点自己做;要加密,端点自己做;要流控,端点自己做。网络保持简单,复杂性留给需要它的人。"

林小源看着大海,若有所思:"TCP 和 UDP 不是竞争关系,而是互补关系。"

"聪明。"UDP 跳下码头,踩在水面上,"TCP 是大船——慢但可靠。我是小船——快但不保证。你选哪个,取决于你要运什么。"

c
/*
 * UDP 的设计哲学:
 *
 * 1. 简单
 *    没有连接管理
 *    没有确认机制
 *    没有流控和拥塞控制
 *
 * 2. 快速
 *    没有握手开销
 *    没有确认延迟
 *    最小的协议头(8 字节)
 *
 * 3. 应用层控制
 *    可靠性由应用层实现
 *    可以实现自定义的重传策略
 *    可以实现自定义的拥塞控制
 *
 * UDP 的常见用途:
 *   DNS — 简单的请求-响应
 *   DHCP — 广播
 *   NTP — 时间同步
 *   视频流 — 可以容忍丢失
 *   游戏 — 实时性优先
 *
 * QUIC:
 *   基于 UDP 的可靠传输
 *   Google 开发
 *   HTTP/3 使用
 */

printf("=== UDP 之道 — 简单即快 ===\n\n");

printf("UDP 的设计哲学:\n\n");

printf("1. 简单:\n");
printf("   没有连接管理\n");
printf("   没有确认机制\n");
printf("   没有流控和拥塞控制\n\n");

printf("2. 快速:\n");
printf("   没有握手开销\n");
printf("   没有确认延迟\n");
printf("   最小的协议头\n\n");

printf("3. 应用层控制:\n");
printf("   可靠性由应用层实现\n");
printf("   可以自定义重传策略\n");
printf("   可以自定义拥塞控制\n\n");

printf("--- UDP 的用途 ---\n");
printf("DNS: 简单的请求-响应\n");
printf("DHCP: 广播\n");
printf("NTP: 时间同步\n");
printf("视频流: 可以容忍丢失\n");
printf("游戏: 实时性优先\n\n");

printf("--- QUIC ---\n");
printf("基于 UDP 的可靠传输:\n");
printf("  Google 开发\n");
printf("  HTTP/3 使用\n");
printf("  内置 TLS 加密\n");
printf("  多路复用\n\n");

printf("--- UDP vs TCP ---\n");
printf("UDP:\n");
printf("  简单、快速\n");
printf("  应用层控制可靠性\n\n");
printf("TCP:\n");
printf("  复杂、有开销\n");
printf("  内核保证可靠性\n\n");

printf("--- 自定义可靠性 ---\n");
printf("应用层可以实现:\n");
printf("  序列号\n");
printf("  确认和重传\n");
printf("  流量控制\n");
printf("  拥塞控制\n");

道藏笔记

内核启示

UDP 的设计哲学是"简单即快"。

UDP 的特点:

  • 简单 — 没有连接、确认、流控
  • 快速 — 最小的协议头,没有握手
  • 应用层控制 — 可靠性由应用层实现

UDP 的用途:

  • DNS、DHCP、NTP
  • 视频流、游戏
  • QUIC(基于 UDP 的可靠传输)

端到端原则:

  • 可靠性在端点实现
  • 网络只负责传输

UDP 是"自由"的——把控制权交给应用程序。


破关试炼

UDP 之道

本章总结无连接、消息式、由应用自担可靠性的传输协议是什么?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道