了解鲍勃·卡恩如何参与构建 TCP/IP,为什么可靠的分组网络很重要,以及这些设计如何持续支撑应用、API 和云服务。

大多数应用看起来很“即时”:你点一下按钮,信息流刷新了,支付完成了,视频开始了。你看不见的是在 Wi‑Fi、移动网络、家庭路由器和数据中心之间(常常跨越多国)移动一小块一小块数据所需的工作——而且你不需要关注其中的琐碎细节。
这种“看不见”正是 TCP/IP 带来的承诺。它不是某个产品或云功能,而是一套共享规则,让设备和服务器以 通常 感觉顺畅可靠的方式互相通信,即使网络有噪声、拥塞或部分故障。
鲍勃·卡恩是让这一切成为可能的关键人物之一。他与文特·瑟夫等合作者一起,塑造了成为 TCP/IP 的核心理念:一种通用的“语言”和一种以应用能信任的方式交付数据的方法。不需要夸大其词——这项工作之所以重要,是因为它把不可靠的连接变成了软件可以可靠构建的基座。
分组网络不是把整条消息当作一个连续流来发送,而是把它拆成称为分组的小片段。每个分组都可以选择自己的路径到达目的地,就像不同的信封通过不同的邮局寄送。
我们会拆解 TCP 如何创造“可靠”的感觉、为什么 IP 有意不作完美承诺,以及分层如何保持系统可理解。读完后,你将能想象当一个应用调用 API 时到底发生了什么——以及为什么这些几十年前的理念依然驱动着现代云服务。
早期计算机网络并不是生来就是“互联网”。它们为特定群体、特定目标而建:这里是一个大学网络,那是一个军方网络,另一个是研究实验室网络。每个网络在内部可能运行良好,但它们常常使用不同的硬件、消息格式和数据传输规则。
这造成了一个令人沮丧的现实:即便两台计算机都“联网”了,它们仍可能无法交换信息。这有点像有许多铁路线,但轨距不同、信号含义也不同。你可以在一个系统内部移动列车,但跨系统移动则很混乱、昂贵或不可能。
鲍勃·卡恩面临的关键问题并不是简单地“把计算机 A 连到计算机 B”。而是:如何把网络彼此连接,使流量能穿过多个独立系统,好像它们是一个更大的系统?
这就是“互联”的含义——为数据提供一种从一个网络跳到下一个网络的方法,即使那些网络设计不同、由不同组织管理。
要让互联在规模上奏效,每个人都需要一套不依赖任何单一网络内部设计的通用规则——协议。这些规则也必须反映现实约束:
TCP/IP 成为实践上的答案:一种共享的“协议约定”,允许独立网络互联并仍能以足够可靠的方式传输数据以支持真实的应用。
鲍勃·卡恩最为人知的是他作为互联网“交通规则”主要架构师之一的角色。上世纪 70 年代,在 DARPA 工作期间,他帮助把网络从一个聪明的研究实验推进到能连接多种不同网络的实践方案——而不强制它们全部使用相同的硬件、布线或内部设计。
ARPANET 证明计算机可以在分组交换链路上通信。但其他网络也在出现——基于无线电的系统、卫星链路和更多实验网络——每个都有自己的特点。卡恩关注的是互操作性:使一条消息可以穿越多个网络,看起来像是在一个网络中传输。
他推动的方法不是去构建一个“完美”的单一网络,而是:
与文特·瑟夫合作时,卡恩共同设计了后来称为 TCP/IP 的体系。一个持久的成果是职责的清晰分离:IP 负责跨网络的寻址与转发,而 TCP 为需要的应用提供可靠交付。
如果你曾调用过 API、加载网页或把容器日志发到监控服务,你都在依赖卡恩倡导的互联模型。你无需关心分组是穿过 Wi‑Fi、光纤、LTE 还是云骨干网。TCP/IP 把这一切看作一个连续的系统——让软件可以专注于功能,而非布线细节。
TCP/IP 背后的聪明理念之一是分层:不是构建一个巨大的“万能”网络系统,而是堆叠更小的模块,每层各司其职。
这很重要,因为网络并不都一样。不同的电缆、无线电、路由器和服务提供商只要同意一些清晰的职责,就能互操作。
把 IP(Internet Protocol) 想象成回答:这些数据要去哪里,如何把它往那个地方推进?
IP 提供 地址(用于标识机器)和基本的 路由(让分组能从网络跳到网络)。重要的是,IP 并不追求完美。它专注于一步步地把分组向前推进,即使路径会变化。
然后 TCP(传输控制协议) 运行在 IP 之上,回答:如何让这感觉像一个可靠的连接?
TCP 处理应用通常需要的“可靠性”工作:按序交付数据、发现丢失的片段并重发、以及调节发送速度以免把接收方或网络压垮。
有用的类比是邮政系统:
你不会要求仅凭街道地址就保证包裹一定安全送达;可靠性是在其之上构建的。
因为职责被分开,你可以改进某一层而不必重设计所有东西。新物理网络可以承载 IP,应用可以依赖 TCP 的行为而无需了解路由细节。正是这种干净的划分,使得 TCP/IP 成为几乎每个应用和 API 之下的隐形、共享的基础。
分组交换是让大规模网络成为可能的理念:你不再为整条消息预留一条专用线路,而是把消息切成小块,独立发送每块。
分组 是包含头部(来源、目的地及其它路由信息)和一小片内容的数据包。
把数据拆成小块有助于:
这里就是“混乱”开始的地方。同一次下载或 API 调用的分组可能会根据当时的拥塞或可用性选择不同路径,这意味着它们可能乱序到达——比如第 12 个分组可能先于第 5 个到达。
分组交换不试图阻止这种情况。它优先保证分组快速通过,即使到达顺序很乱。
丢包并不罕见,也并不总是某人的过错。常见原因包括:
关键的设计选择是允许网络不完美。IP 专注于尽力转发分组,而不承诺交付或顺序。正是这种自由让网络可以扩展——也因此出现更高层(如 TCP)来整理混乱。
IP 以“尽力而为”方式交付分组:有些分组可能迟到、乱序、重复或根本丢失。TCP 运行在其上,创造出应用可以信任的东西:一个单一的、有序且完整的字节流——这正是你上传文件、加载网页或调用 API 时所期望的连接类型。
当人们说 TCP“可靠”时,通常指:
TCP 把数据拆成块并用 序号 标记它们。接收方返回 确认(ACK) 表示已收到的序列。
如果发送方在预期时间内未看到 ACK,就假定有丢失并进行重传。这是核心的“幻觉”:即使网络可能丢包,TCP 也会不断尝试,直到接收方确认收到为止。
两者听起来相似,但解决不同问题:
两者共同作用,帮助 TCP 在不鲁莽的前提下保持高效。
固定超时在快网和慢网都不适用。TCP 根据测得的往返时延不断调整超时。如果网络状况变差,TCP 在重传前会等更久;如果变快,则更敏捷。正是这种适配,使得 TCP 能在 Wi‑Fi、移动网络和远距离链路上持续工作。
TCP/IP 最重要的理念之一是端到端原则:把“智能”放在网络两端(端点),并保持网络中间相对简单。
端点即真正关心数据的设备和程序:你的手机、笔记本、服务器以及运行在其上的操作系统和应用。网络核心——中间的路由器和链路——主要关注的是转发分组。
与其试图让每个路由器都“完美”,TCP/IP 接受中间会不完美,让端点处理需要上下文的信息。
保持网络核心更简单使互联网更容易扩展。新网络加入时不需要每一个中间设备都理解每个应用的需求。路由器不需要知道某个分组属于视频通话、文件下载还是 API 请求——它们只需转发。
在端点,你通常处理:
在网络中,主要处理:
端到端思想易于扩展,但它把复杂性往外推。操作系统、库与应用需要承担“让它在混乱网络上运行”的责任。这很好,因为更灵活,但也意味着错误、配置不当的超时或过度激进的重试会带来真正的用户体验问题。
IP(Internet Protocol)做了一个简单承诺:它会尽力把你的分组朝目的地移动。仅此而已。它不保证分组会到达、不保证只到一次、不保证顺序或在特定时间内到达。
这听起来像个缺陷——直到你看到互联网需要成为怎样的东西:由许多较小网络组成的全球网络,这些网络由不同组织拥有,不断变化。
路由器是 IP 的“交通指挥官”。它们的主要工作是转发:分组到达时,路由器查看目的地址并选择当前看来最佳的下一跳。
路由器不会像电话交换机那样跟踪会话。它们通常不为你保留带宽,也不会等待确认分组已通过。通过让路由器专注于转发,网络核心保持简单——能扩容到巨量设备与连接。
保证是昂贵的。如果 IP 试图保证每个分组的交付、顺序和时序,那么地球上每个网络都要紧密协调、保存大量状态,并在故障时以相同方式恢复。这种协调会减缓增长并放大故障影响。
相反,IP 容忍混乱。如果一条链路失败,路由器可以把分组走另一条路;如果路径拥塞,分组可能被延迟或丢弃,但流量通常能通过替代路径继续前进。
结果就是弹性:即便部分网络发生故障或变化,互联网仍能继续工作——因为网络不被迫完美,仍然能发挥作用。
当你用 fetch() 请求一个 API、点击“保存”或打开 websocket 时,你并不是在“与服务器进行一条平滑的对话”。你的应用把数据交给操作系统,操作系统把它拆成分组并把这些分组发到许多独立网络——每一跳都在做自己的决策。
常见的惊讶:你可能有很高的吞吐量,但界面仍然卡顿,因为每次请求都在等待往返。
TCP 会重传丢失的分组,但它无法知道对你的用户体验来说“太久”是什么意思。这就是为什么应用会额外实现:
分组可能被延迟、乱序、重复或丢失。拥塞会突发性提高延迟。服务器可能已响应,但响应没有到达你这端。这些表现为 flaky 测试、随机 504 或“我的机器上能跑”的问题。通常代码没问题——是机器之间的路径在捣乱。
云平台看起来像一种全新的计算形态:托管数据库、无服务器函数、“弹性扩展”。但在底层,你的请求仍然依赖鲍勃·卡恩促成的 TCP/IP 基础:IP 在网络间移动分组,TCP(或有时是 UDP)决定应用如何体验网络。
虚拟化和容器改变了软件运行的位置和打包方式:
但这些是部署细节。分组仍使用 IP 寻址和路由,许多连接仍依赖 TCP 进行有序可靠传输。
常见的云架构由熟悉的网络构件搭建:
即便你“看不见” IP 地址,平台也在分配它们、路由分组并在背后跟踪连接。
TCP 能从丢包中恢复、重排序并适应拥塞——但它不能承诺不可能的事。在云系统中,可靠性是团队工作:
这也是为什么能生成并部署全栈应用的平台(比如 Koder.ai)仍然依赖相同的基础:当应用与 API、数据库或移动客户端通信时,你又回到了 TCP/IP 的世界——连接、超时、重试等问题依然存在。
当开发者说“网络”时,通常是在 TCP 和 UDP 两个传输机制之间做选择。两者都运行在 IP 之上,但做了不同的权衡。
当你需要数据按序到达且宁可等待也不愿出错时,TCP 是很好的选择。想想:网页、API、文件传输、数据库连接。
这也是日常互联网很大一部分运行在它之上的原因——HTTPS 运行在 TCP 之上(通过 TLS),大多数请求/响应软件都假定 TCP 的行为。
代价是:TCP 的可靠性会增加延迟。如果某个分组丢失,后续分组可能被阻塞直到缺口填补(“首部阻塞”)。对交互体验来说,这种等待感可能比偶尔的故障更糟糕。
UDP 更像是“发了就希望它到达”。UDP 层没有内建的顺序、重传或拥塞处理。
当及时性比完美更重要时,开发者会选择 UDP,例如实时音视频、游戏或实时遥测。很多此类应用会按用户感知构建自己的轻量可靠机制(或选择不做任何可靠性处理)。
一个现代重要例子:QUIC 运行在 UDP 之上,让应用能更快建立连接并规避一些 TCP 的局限——而无需改变底层的 IP 网络。
基于以下选:
TCP 常被称作“可靠”,但这并不意味着你的应用总会感觉可靠。TCP 能从许多网络问题中恢复,但不能保证低延迟、一致吞吐或当两台系统之间路径不稳时仍有良好体验。
丢包 会迫使 TCP 重传。可靠性得以保留,但性能可能崩溃。
高延迟(长往返时间)会让每个请求/响应周期变慢,即便没有丢包。
缓冲膨胀(bufferbloat) 发生在路由器或操作系统队列积压过多数据时。TCP 看到的丢包减少了,但用户体验是巨大延迟与“卡顿”。
不当的 MTU 配置 会导致分片或黑洞(当分组“太大”时消失),引发看似随机的超时故障。
你经常不会看到明确的“网络错误”,而会看到:
这些症状真实存在,但不总是由你的代码引起。它们往往是 TCP 在执行其工作:重传、退避与等待——而你的应用时钟仍在转动。
先做个基本分类:问题主要是丢包、延迟还是路径变化?
如果你在快速构建(例如在 Koder.ai 中原型化并部署服务),把这些可观测性基础纳入初始“规划清单”是值得的——因为网络故障通常首先表现为超时与重试,而不是整洁的异常。
假设网络会出问题。使用超时、带指数退避的重试,并使操作具备幂等性,以防重试造成重复计费、重复创建或状态损坏。
TCP/IP 是一组共享的网络规则,允许不同的网络互联并以可预测的方式传输数据。
它之所以重要,是因为它让不可靠、异构的链路(Wi‑Fi、LTE、光纤、卫星)对软件可用——因此应用可以假设可以发送字节并获得响应,而无需了解物理网络的细节。
鲍勃·卡恩推动了“互联网互联(internetworking)”的理念:将网络彼此连接,而不强制它们采用相同的内部硬件或设计。
与合作者(尤其是文特·瑟夫)一起,他的工作促成了那种分工:IP 负责跨网络寻址与路由,TCP 在其之上为应用提供可靠性。
分组交换把一条消息拆成一小块一小块的分组(packet),每个分组可以独立传输。
优点:
IP 的任务很单一:把分组往目标地址推进。它不保证到达、不保证顺序,也不保证时延。
这种“尽力而为”的模型之所以能在全球扩展,是因为路由器可以保持简单快速,网络在链路故障、路径变化和新网络加入时仍能继续工作。
TCP 把 IP 的尽力而为的分组变成对应用友好的有序字节流。
它通过:
从而让不可靠的网络看起来可靠。
它们解决不同问题:
良好性能需要两者并存:发送方既要尊重接收方,也要顾及网络。
分层把职责分开,使每一层都能独立演进。
对开发者而言,这意味着可以构建 API,而不用为每种网络类型重设计应用。
端到端原则 意味着在网络核心(路由器)保持相对简单,把“智能”放在端点。
实际后果:应用和操作系统负责可靠性、超时、重试和加密(通常是通过 TLS),因为网络无法为每个应用量身定制行为。
延迟 是往返时间,会影响“唠叨式”模式(大量小请求、重定向、重复调用)。
吞吐量 是每秒传输字节数,影响大文件传输(图片、备份、视频)。
实用建议:
根据需求选择:
经验法则:如果是请求/响应且以正确性为先,通常从 TCP(或通过 HTTP/3 的 QUIC)开始。