全书骨架:从应用往下拆
自顶向下不是炫技,而是一条教学法:先建立「用户能看见的服务」,再追问服务是怎么被下层兑现的。八章因此形成一条单向依赖链——每一章都以上一章提出的需求为输入。
每一层先列出服务模型(可靠与否、保序与否、有无拥塞控制),再讲协议如何用报文交换兑现这些承诺。
第 8 版把「包怎么被转走」和「转发表怎么被填上」拆开。SDN 不再是附录彩蛋,而是控制平面的第二种组织方式。
时延四组分、吞吐瓶颈、端到端往返、滑动窗口流水线,这些数量级判断比记住某个标志位更重要。
前七章先把明文协议讲清楚,第八章再把机密性、完整性、认证与运行时防护叠回去。
读法建议:每一章先画服务模型,再看报文怎么兑现,最后才碰字段。 章末的易错点是复习入口,不是边栏彩蛋。 配套作业(套接字、Wireshark)比把目录背下来更能把自顶向下读成「自己的方法」。 第 8 版正文之外还有多媒体等选读,本笔记不覆盖——先把八章主线走通,再按兴趣补。 和《系统方法》对照着读时,用这一本建立服务直觉,用那一本追问每项功能该放在哪一层。 自测题放在文末,建议每读完两章做一遍对应题,而不是攒到最后一天。 站内演示用来验证机制,RFC 精读用来核对字段;笔记本身只负责骨架和易错点。 第八章可以与运维安全专题对照着读,但先把威胁模型画完再看产品名词。
- 第二章结束时应能独立写出一次页面抓取里 DNS、连接、对象、缓存各干什么。
- 第三章结束时应能把可靠传输台阶画到选择重传,再指出 TCP 用了其中哪些。
- 第四、五章结束时应能分开回答「这包为何从这端口出去」和「这表项是谁写下的」。
- 第六章结束时应能口述一帧如何带着 MAC 走过交换机、又如何在路由器上被换成新的下一跳。
- 第七章结束时应能把「卡住」拆成误码、切换、拥塞三条候选链,而不是只骂 TCP。
- 读完第八章,回头给前七章的明文协议各补一条信任边界。
- 卡在数量级时回到第一章的时延四组分,不要先去翻某个标志位的定义。
- 卡在「这张表是谁填的」时,停在第五章,不要在数据平面里找路由协议。
计算机网络和因特网 —— 先建立全景
开篇不急着讲协议字段,而是同时给出两幅图:硬件拼装图(主机、接入、路由器、链路)和服务图(应用向网络要什么)。后面所有章节都是在给这两幅图填零件。
边缘、接入与核心
网络边缘是运行应用程序的端系统。接入网把端系统接到第一跳路由器:家庭宽带、企业以太网、蜂窝无线,物理介质从双绞线、同轴、光纤到无线电。 家庭侧常见「调制解调器加家用路由器」;校园和企业侧则是以太网交换机堆叠后再上连路由器;蜂窝侧由基站接入核心网。物理介质决定的是带宽、误码和部署成本, 并不决定上层用哪种协议。
网络核心是互联的分组交换机。两种交换哲学对照着讲:电路独占一条预留通路,适合可预期的恒定负荷;分组把报文切成包,在链路上统计复用,适合突发流量。因特网选择后者, 代价是排队与丢失,收益是空闲者不占死资源。 存储—转发意味着一个分组必须整包收齐才能开始送出下一跳,因此跳数和分组长度都会叠进总时延。电路交换里的时分、频分是「把管道切成专用细管」; 分组交换里没有这种预先切管,只在分组真正占用链路的那些微秒里才消耗容量。
时延、丢失与吞吐
一个分组从源到宿的时延可拆成处理、排队、传输、传播四段。处理是查表与校验,通常是微秒量级;排队取决于当时的拥塞,从接近零到几十上百毫秒都常见; 传输是「比特数 ÷ 链路速率」;传播是「距离 ÷ 信号速度」。 四段里只有排队是随机的,也因此成为服务质量讨论的中心。缓存溢出就丢包;有的链路层会在一跳内重传,有的把恢复留给运输层。
吞吐要分瞬时与平均。文件传输关心的是全程平均;实时通话关心的是会不会突然掉到编码器最低档以下。路径吞吐由最窄的那一跳决定——这就是瓶颈链路。 两条共享瓶颈的流会互相压对方的平均速率。 后面讲 TCP 窗口和视频自适应码率时,都会回到「时延四组分 + 瓶颈吞吐」这张草图,而不是去背某个协议字段。
协议分层与服务模型
协议是实体之间关于报文格式、时序和错误处理的约定。因特网协议栈习惯画成五层:应用、运输、网络、链路、物理。每一层只跟上下相邻层打交道, 用头部封装把本层控制信息贴在载荷前面。 发送时自上而下加头,接收时自下而上剥头。同一台主机里,分层是软件模块的边界;在一条路径上,对等层才是真正「对话」的双方。
分层的好处是可以替换实现而不改接口:光纤换成无线,浏览器不用重写。代价是各层可能重复类似功能(可靠传输、差错检测), 也可能出现跨层性能问题——例如把丢包一律解释成拥塞。 服务模型是层与层之间的合同:网络层提供的是尽力而为的主机到主机数据报,运输层再决定要不要把它加成可靠字节流。安全在开篇只点到威胁面: 嗅探、伪装、篡改、拒绝服务——细节留给最后一章。 读史部分只需带走一句:今天的因特网是分组、无连接、端系统复杂而核心相对简单的那条路线赢下来的结果,不是唯一可能的设计。
存储转发与统计复用的数量级
在一条由若干路由器串起来的路径上,存储转发让每个节点都把「收齐再转发」的时间叠进去。分组越长、跳数越多,这笔固定成本越大;把大报文切小可以让流水线更细, 但头部开销上升。 统计复用的好处只有在流量真正突发时才显著:若所有用户同时以峰值发送,分组网络并不会凭空变出容量。
读完第一章,应能不查书回答:主机、接入、路由器、链路各自干什么;电路与分组各自牺牲什么;四段时延里哪一段随拥塞变、哪一段随距离变; 五层模型里「对等层对话、相邻层服务」是什么意思。 后面七章都是在给这张草图加零件,而不是另起炉灶。
- 先画路径,再往链路上标注速率与距离,最后才谈协议字段。
- 吞吐看瓶颈,时延看四组分之和,不要用一个「快慢」糊弄过去。
- 分层是接口合同,不是自然界的分层;重复功能和跨层副作用都是合同的代价。
应用层 —— 网络存在的理由
应用层决定进程之间说什么话。协议本身只是报文格式、时序与错误处理的约定;真正跑在主机上的是实现这些约定的客户端与服务器程序。
应用体系结构与运输服务需求
两种经典结构:客户—服务器依赖始终在线的知名主机;对等结构让终端互相提供服务,扩展性更好,但要处理动态加入、NAT 穿透与激励。实际系统常常是混合体: 目录或信令走服务器,数据走终端之间的直连。 进程用 IP 地址加端口号标识套接字,应用协议则规定这些套接字上交换的报文长什么样。
不论哪种结构,应用都要向运输层点菜:要不要可靠交付、要不要保序、能否容忍时延抖动、是否在意吞吐、要不要保密。Web 与邮件通常选可靠字节流; 实时音视频往往宁可丢几帧也不愿卡住,于是更靠近数据报服务。 带宽敏感的应用还关心「最小可用吞吐」,交互应用关心「往返不要超过人能察觉的阈值」。这些需求并不会自动被满足, 它们只是后续选 UDP、TCP 还是在应用里自建控制回路的依据。
Web 与 HTTP
HTTP 是无状态的请求—响应协议:服务器默认不记得上一次你是谁。请求行给出方法、目标与版本,头部补充主机、缓存、内容类型、cookie 等信息,
可选的消息体携带提交数据。
常见方法里,GET 取资源,POST 提交,还有用于上传、删除和探活的一组语义。
状态码把结果分成成功、重定向、客户端出错和服务器出错几大类,应用应当按类别而不是只认「200 或不是」来处理。
Cookie 把一小段状态存到浏览器,让无状态协议能支撑登录与购物车。 连接管理经历了「一对象一连接」、持久连接、流水线,再到后来在单一连接上多路复用的演进——第 8 版会点到 HTTP/2 的二进制分帧与头部压缩, 以及 HTTP/3 把运输改到 QUIC 上、把握手和丢包恢复从操作系统 TCP 里挪走的方向。 缓存与条件请求(按修改时间或实体标签验证)是降低时延和骨干流量的主杠杆;命中时连源站都不必惊动。CDN 则是把缓存搬到用户附近的工业化形态: 用 DNS 或 HTTP 重定向选边,用一致性哈希一类方法放对象。
电子邮件与 DNS
邮件是「推」的代表:用户代理把信件交给自己的邮件服务器,服务器之间用 SMTP 接力,收信端再用独立协议把信拉回邮箱。 HTTP 是拉,SMTP 是推,所以垃圾邮件、中继策略和发送方认证会变成邮件系统自己的难题。 信件格式(信封与内容、头部与正文)和应用协议要分开看:传输协议只保证把对象交给下一跳邮件服务器,并不理解你在正文里写了什么。
DNS 是因特网的目录服务。它不只把主机名换成 IPv4/IPv6 地址,还提供邮件交换机、别名、以及后来大量应用把控制面信息塞进 TXT 等记录的用法。 查询沿根、顶级域、权威服务器逐级走,但绝大多数答案在递归解析器或本地缓存就被拦住。层次加上缓存,才让一套全球命名系统扛得住查询量。TTL 决定缓存能放多久: 太长则变更生效慢,太短则根和权威被反复敲打。 读 DNS 时要分清递归查询与迭代查询、权威回答与非权威回答,否则排障时会把「解析器缓存了旧值」错判成「权威服务器配错了」。
流媒体、CDN 与套接字
流媒体把大对象切成可独立解码的块,播放器按近期吞吐选码率档位。缓冲是在时延和卡顿之间做买卖:缓冲深则更抗抖动,起播更慢。 CDN 用就近进入、DNS 或 HTTP 重定向把用户引到边缘节点,源站只处理未命中与动态内容。对等分发则证明:若每个新加入者同时也上传,完成时间可以随节点数改善, 而纯客户—服务器会被源站上行瓶颈卡住。
章末的套接字编程把抽象落到 API:UDP 套接字几乎是「把数据报扔给某地址某端口」,报文边界保留,发送也不保证到达;TCP 套接字先有监听与接受, 再在已连接的字节流上读写,应用看到的是字节而不是报文。 读完这一节,后面运输层不再是黑盒——你已经知道应用究竟向操作系统要了哪种服务。
- 先写清应用的可靠性、时延、吞吐需求,再决定运输服务,不要倒过来选。
- HTTP 的对象、连接、缓存是三件独立的事,改其中一件不必推翻另外两件。
- DNS 既是目录,也是控制面;缓存命中才是常态,根查询是例外。
运输层 —— 进程到进程的交付
网络层只负责把分组送到主机;运输层用端口把到达的字节交给正确的进程,并在需要时补上可靠、保序、流量控制与拥塞控制。
复用、UDP 与可靠传输原理
发送方用源端口、目的端口(再加地址)标识一条会话,接收方按这些字段分流,这就是复用与分解。无连接分解只看四元组中的目的侧;面向连接的分解还要匹配已经建立的套接字。 知名端口方便客户端找到公共服务,临时端口则由操作系统分配给发起方。
UDP 几乎只做复用这件事:加上端口与校验和就发出去,不管丢失、失序或重复。校验和用反码和,覆盖伪头部、UDP 头和数据,只能发现部分差错。 它的价值是简单、头部短、不建立连接、保留报文边界,适合 DNS 查询、实时媒体和那些宁可自己管可靠性的应用。应用若在 UDP 上自建确认与重传, 本质上是在用户态重写一截精简的可靠运输。
可靠传输则被拆成一套递进的思想实验:先假设信道完美,再引入比特差错(校验和加确认加重传),再引入丢失(定时器),再处理重复与序号,最后用流水线提高带宽利用率。 停等协议在「时延带宽积」很大时会把链路用得很空。 回退 N 步把未确认窗口整段重发,实现简单、重传浪费大;选择重传只补丢失的序号,接收方要更大的乱序缓存。 这套「原理先于 TCP」的讲法,是本书运输层最好用的部分——读到真实 TCP 时,你看到的是这些积木的工程组合,而不是从零冒出来的魔法。
TCP:连接、可靠字节流与流量控制
TCP 向上提供面向连接的可靠字节流。段里带着序号、确认号、窗口、标志位和校验和。 三次握手交换初始序号并确认双方都能收发;数据阶段用累计确认、超时重传、快速重传与选择确认一类机制填补丢失;关闭阶段两个方向各自半关闭,所以常见四次挥手。 连接不是电路,只是两端控制块里的状态:序号空间、窗口、定时器和往返估计。
超时时间不能拍脑袋。协议用平滑往返样本再加偏差项估一个超时值:变化大时超时更保守,避免过早重传把网络打得更堵。 流量控制用接收窗口通告自己还能装多少字节,防止发送方淹没接收应用;窗口为零时发送方仍会探询,以免通告丢了之后双方永远卡住。滑动窗口让「等确认」变成流水线, 窗口大小同时受接收方通告和拥塞窗口约束。 字节流没有应用报文边界,粘包和拆包是应用自己的事。
拥塞控制及其演进
因特网把拥塞控制主要放在端系统:发送方根据丢包或时延信号估计路径容量。核心保持相对简单,换来的是端系统必须守规矩——这也是后来出现各种互操作性争论的根源。 经典故事是慢启动把窗口指数抬升,到达阈值后进入拥塞避免再线性探测,超时则把阈值砍半并回到慢启动,三次重复确认触发快速重传与快速恢复。 加性增、乘性减被用来说明多流共享瓶颈时的公平趋向:它不是道德口号,而是一种让系统回到可行域的控制律。
第 8 版会把视线扩到后来在操作系统里更常见的 CUBIC(用窗口增长函数更好地填满高带宽时延积路径),以及以带宽—时延积为目标、不完全依赖丢包的测量型控制。 显式拥塞通知让路由器可以「先标记再丢弃」,但要端系统识别标记才有效。应用开发者需要记住:你看到的「网速」,往往是这条拥塞控制状态机的输出,而不是链路标称速率。 短连接可能还没走完慢启动就结束了,这时时延和握手次数比稳态算法更致命——这也是 QUIC 一类设计把握手和应用数据叠在一起的动机。
从套接字回看运输层
应用调用 connect 时触发握手,调用 send 时数据进入发送缓存并受窗口约束,调用 close 时启动半关闭。
运输层对应用隐瞒了重传、乱序重组和拥塞窗口,但隐瞒不是消失:短连接的延迟往往耗在握手和慢启动,不耗在稳态算法。
UDP 则几乎不隐瞒——报文边界、丢失和失序都会直接冒到应用里。
- 端口是进程级的复用键,不是安全边界。
- 可靠传输的台阶(差错 → 丢失 → 流水线)比背 TCP 标志位更重要。
- 发送方可发量 = min(接收窗口, 拥塞窗口),两个窗口对应两个保护对象。
网络层:数据平面 —— 包怎样被转走
第 8 版把网络层一劈为二。本章只关心已经算好的转发表如何把到达的分组送出某个端口,以及 IP 地址、分片、NAT 与中间盒如何改写分组。
转发与路由是两件事
转发是数据平面上的逐包动作:查表、改头、从某端口送出,要求线速。路由是控制平面上的决策过程:交换信息、计算路径、填写那张表,可以慢得多。 把这两件事揉成「路由器会自己找路」一句话,后面就无法理解 SDN,也无法理解「表是对的但队列已经爆了」这类故障。
路由器内部大致分成输入端口(线卡终结、查表)、交换结构、输出端口(排队、调度)和一张被控制平面喂养的转发表。 输入端查表跟不上或交换结构争用,会造成输入阻塞;输出端容量不够,会造成输出排队——绝大多数可见拥塞发生在这里。 传统设备按目的地址最长前缀匹配;SDN 风格的通用转发则按匹配—动作规则处理更多字段,防火墙、负载均衡也可以看成同一抽象的特例。中间盒之所以难对付, 是因为它们让「按目的地址转发」不再是唯一故事。
IPv4 数据报与编址
IPv4 数据报携带版本、头部长度、服务类型、总长度、标识与分片信息、生存时间、上层协议号、头部校验和以及源与目的地址。生存时间每过一跳减一,防止环路包永远转圈。 头部校验和只覆盖 IP 头,载荷完整性留给运输层。地址不再按早期的 A/B/C 类硬切,而是用前缀长度表示网络部分,即无类别域间路由。聚合让骨干表不至于按主机膨胀; 最长匹配则保证更具体的子网能从大块里被正确分出。
子网把一块前缀再切给链路,主机地址里网络前缀相同的节点共享一条广播域。DHCP 用发现、提供、请求、确认四步让主机开机后自动拿到地址、掩码、默认网关和解析器地址。 NAT 让内网私有地址共享少量公网地址,改写运输层端口以区分会话;它缓解了地址耗尽,也破坏了纯端到端的可达性,对等应用因此要打洞或借助中继。 分片发生在 MTU 不够时,IPv4 允许中间路由器切开数据报,接收端再重组——许多网络丢掉「需要分片」的 ICMP 后,大包会莫名黑洞。 这就是路径 MTU 发现变得既重要又脆弱的原因。
IPv6、中间盒与编程接口
IPv6 把地址拉长到 128 位,简化固定头部,把校验和移走,取消中间节点分片,用扩展头承载可选功能。分片若发生,只应由源端来做。 邻居发现、无状态地址配置和多播取代了 IPv4 里 ARP 与部分 DHCP 的角色。过渡期的双栈、隧道与地址转换是工程现实,不是理论附录:两套地址空间长期并存, 应用必须能同时处理两种套接字。
中间盒(NAT、防火墙、性能增强代理)打破了「只有端系统改应用数据」的朴素图景:它们让部署方便,也让端到端假设变脆。对应用而言, 网络层最重要的接口仍是「把数据报交给某目的地址」,细节被套接字库挡住。 但一旦你开始排「某条路径只能过小包」「某应用过不了网关」这类故障,就必须把中间盒重新画回图里。
最长前缀的直觉
一张转发表里可以同时有 10.0.0.0/8 和 10.1.2.0/24。发往 10.1.2.8 的包必须走更具体的那条,
否则聚合就变成了误伤。
这就是最长前缀匹配存在的理由。默认路由是长度为 0 的前缀,只有在什么都匹配不上时才用。主机上的路由决策更简单:目的与我同一子网就直接交付,否则交给默认网关。
- 转发是热路径,路由是冷路径;SDN 改变的是谁来填表,不是要不要表。
- CIDR 把「网络号多长」从类别里解放出来,查找规则随之变成最长匹配。
- NAT 和中间盒让「地址在全程不变」变成有条件的真话,排障时要把改写点画出来。
网络层:控制平面 —— 表是怎样填上的
数据平面只会执行表。控制平面决定表里写什么:传统上每台路由器自己跑路由协议,后来也可以由逻辑集中的控制器算好再下发。
链路状态与距离向量
两种经典算法回答同一问题:在带权图上找最短路径。链路状态让每个节点广播自己的邻接信息,大家独立跑同一套最短路计算(思想上来自 Dijkstra),收敛快, 但要可靠洪泛、同步的拓扑数据库,以及处理过期通告。 距离向量只跟邻居交换「到各目的地的开销」,用分布式松弛(思想上来自 Bellman-Ford)迭代,实现简单,却有计数到无穷、坏消息传得慢等固有毛病; 毒性逆转、水平分割之类补丁能缓解,不能从根上消灭。
度量可以是跳数、带宽、时延或管理员设定的代价。错误的度量会让流量走「看起来短、实际很堵」的路;动态度量若反馈太急,还可能自己振荡。 控制平面的正确性不只是「算得出一条路」,还包括:环路能消、分区能发现、错误通告能被认证挡下。这些要求决定了后面 OSPF 和 BGP 为什么远比课堂上的伪代码复杂。
域内 OSPF 与域间 BGP
一个自治系统内部常用链路状态风格的 OSPF:区域分层减轻洪泛范围,骨干区域把各区域的汇总接起来,认证防止乱报拓扑。同一 AS 里的目标函数相对一致, 所以「最短路」说得通。 IS-IS 在服务商网络里扮演类似角色,思想同类。域内还可以看到 RIP 这类距离向量的历史身影,今天更多作为小网络或教学对照。
自治系统之间则是 BGP。BGP 不追求全局最优,而追求策略可行:哪些前缀愿意宣告、愿意从谁收、出口怎么选,都是商业关系的编码。 客户—对等—提供者关系决定了默认的导入导出策略。 路径向量带着 AS 列表,用来检测环路;本地优先级、AS 路径长度、多出口区分等属性远比「跳数最小」丰富。热土豆路由让流量尽早离开自己的网络, 冷土豆则尽量在自己骨干里带到更近的出口。 读到这里应能解释:为什么两台主机之间的路径常常不是地理最短,以及一次错误的路由宣告何以能把流量吸到错误的地方——控制平面的一条更新,可以改写全球数据平面。
ICMP、SDN 与网络管理
ICMP 是网络层的信使:不可达、超时、回显请求与应答,是 ping 和 traceroute 一类工具的底座。
它不是「另一种用户数据协议」,而是控制与诊断信道;过滤过头会让排障失明,完全放开又可能被滥用。traceroute 利用 TTL 耗尽产生的超时消息画出路径,
中间盒若沉默,画出的图就会缺段。
SDN 把控制平面从设备里抽出来:交换机变成「匹配—动作」执行器,控制器掌握全局视图,南向通道下发流表。 好处是策略集中、演化快,做流量工程和细粒度隔离不必等设备厂商改协议;代价是控制器可用性、控制通道时延、流表规模和一致性都变成新问题。逻辑集中不等于物理单点, 生产里控制器自己也是一套要设计的分布式系统。 配置管理、SNMP 一类传统管理协议,以及更新的遥测与自动化,回答的是另一件事:表不仅要算对,还要能被看见、被审计、被回滚。
控制平面会怎样出错
数据平面的故障常常是局部的:某端口 down、某队列满。控制平面的故障可以是全局的:错误度量引起振荡,错误宣告把流量吸走,认证缺失让假邻居改写你的表。 收敛期间还可能出现临时环路——表已经不一致,包在几台路由器之间转圈直到 TTL 耗尽。读控制平面,要同时问「稳态对不对」和「变化时会乱多久」。
- 链路状态换的是全网拓扑,距离向量换的是邻居的意见。
- OSPF 求域内最短,BGP 求策略可行,不要共用同一套「最优」词汇。
- SDN 把算路集中,并不消灭一致性、可用性和控制时延这些问题,只是换地方出现。
链路层和局域网 —— 一跳之内如何交付
链路层负责相邻节点之间的一跳:成帧、检错、多路访问、以及用硬件地址在交换式局域网上把帧送到正确端口。
成帧、检错与多路访问
发送方把网络层数据报装进帧,加上本跳需要的地址与校验。成帧要解决「比特流从哪开始、到哪结束」:可以用特殊定界符并在数据里转义,也可以靠长度字段。 检错常用循环冗余校验:把比特串看成多项式,除以双方约定的生成多项式,余数贴在帧尾;接收方重算以判断是否在链路上被改过。奇偶校验和因特网校验和更轻,检错能力也更弱。 纠错还能恢复少量比特翻转,适合误码高、重传贵的信道;局域网更常检错后丢弃,把恢复留给上层。
共享介质需要多路访问协议。把信道切成时隙、频段或码字的是信道划分;先听再发、冲突后退的是随机访问;轮询或令牌是轮转。ALOHA 说明纯随机访问在负荷高时效率会塌; 时隙化和载波侦听是在这个方向上的改进。 以太网的历史从共享总线加冲突检测走到全双工交换,冲突从「日常事件」变成「教学概念」——但随机访问的思想在无线里还活得很好。
以太网、ARP 与交换机
交换式以太网是今天有线局域网的默认形态。帧带着目的与源 MAC、类型字段和帧校验。交换机自学源 MAC 与端口的对应关系,未知目的就泛洪,已知则只从对应端口送出; 表项超时以免主机搬家后指错。 生成树一类协议用来打破物理环,避免广播帧永无止境地转圈。VLAN 把一台物理交换机切成多个广播域,跨交换机再用标签把同一逻辑网延续过去。
ARP 在「我知道下一跳 IP,但本链路上要写 MAC」时出场:广播询问,缓存回答。缓存过期策略和代理 ARP 都会成为排障点。 交换机转发帧时通常不改 MAC,路由器转发分组时会剥掉旧链路头、换上新的下一跳 MAC——上一跳与下一跳的分界就在这里。同一条端到端路径上,IP 地址尽量保持不变, MAC 地址几乎每过一跳就换一次。
链路虚拟化、数据中心与一日回顾
MPLS 一类技术在链路与网络之间插入标签转发:入口给分组贴标签,中间只按标签交换,出口再剥掉。它让流量工程和 VPN 更好做, 也模糊了「这到底算链路还是算网络」的教科书边界。 数据中心网络强调多路径、东西向流量和大规模二层或叠层方案:服务器之间的流量往往大于进出数据中心的流量,传统三层树容易在根部阻塞。
章末常把一条 Web 请求再走一遍:本机缓存、DNS、ARP、以太网、IP 转发、TCP 握手、HTTP、页面里后续对象——用来证明各章零件已经能咬合。 读到这里,封装不再是抽象词:每一层加头,对应一跳或一端的控制信息。若你能不看笔记把这条路径口头走通,自顶向下的前六章就真正连成了一张图。
广播、环路与生成树
学习型交换机在未知单播和广播时会向除入端口外的所有端口转发。若物理上存在环,这些帧会自我放大,直到链路被打满——这就是广播风暴。 生成树协议通过逻辑上阻断部分端口把拓扑收成树,换来的是部分链路平时闲置。 数据中心后来用多路径和叠层,正是为了不再用「砍成树」换无环。
- 一跳的地址是 MAC,全程的地址是 IP;过路由器必换链路头。
- 碰撞域已被交换式以太网切碎,广播域要靠 VLAN 或路由器来切。
- 封装不是比喻:每一层的头对应一跳或一端真正要用的控制信息。
无线与移动网络 —— 链路会动、主机也会动
无线不只是「没有网线的以太网」。信道会衰减、干扰、隐藏终端;主机还可能在通信过程中换接入点甚至换网络。协议必须同时处理差链路和移动性。
无线链路的独特之处
无线电受到路径损耗、多径、遮挡和干扰的影响,误码率随时间和位置剧烈变化。信噪比决定在给定频段里大致能挤出多少可靠比特。 隐藏终端让「我听着空闲」不等于「对端也空闲」;暴露终端则可能让你不必要地闭嘴。 因此无线局域网常用冲突避免而不是有线那种边发边听的冲突检测:发送前预约或随机退避,必要时用短控制帧探路。链路速率还会自适应调制,信号差就降速保连通。
码分一类技术允许用户在同一时段、同一频段上靠码字分离,这在蜂窝里更常见。无论用哪种共享方式,无线链路的「容量」都是位置、干扰和时间的函数, 不能当成一根固定速率的网线。 上层若把无线丢包当成拥塞信号,窗口就会在用户走过走廊时无谓回落。
Wi-Fi 与蜂窝
802.11 网络分基础设施模式与自组织模式。基础设施模式里,站点扫描、认证、关联到接入点,接入点再桥到有线局域网;同一扩展服务集内可以漫游。 分布式协调功能是默认的媒体访问方式;点协调是中心调度的备选。 关联、鉴权、加密管理帧与数据帧,是安全一章在无线场景的预告:开放网络、预共享密钥和企业级认证对应完全不同的信任模型。
蜂窝网走另一条中心化更强的路:频谱授权、基站覆盖、核心网负责鉴权、移动性与会话。 第 8 版把 4G/5G 作为现行对象来讲:无线接入与核心网分离、控制与用户面分离,移动性由网络侧锚定而不是只靠主机自己换地址。 基站之间的切换要在中断时间和状态迁移之间折中。 对应用开发者,蜂窝和 Wi-Fi 的差别往往先表现为时延分布、计费和地址/NAT 行为,而不是空口调制细节。
移动性对上层的冲击
换接入点但还在同一二层域,上层几乎无感。换了 IP 前缀,运输层连接的四元组就断了。 解决思路大致两类:让网络在移动过程中保持一个稳定的锚地址(移动 IP 一类「家乡代理 + 转交地址」),或让应用/运输层自己能迁移(多路径、连接迁移、应用重连)。 锚在网络里的方案对旧应用友好,却引入三角路径和代理可用性;锚在端上的方案更灵活,却要求协议栈或应用配合。
无线丢包还会愚弄把「丢包≈拥塞」当作公理的拥塞控制,使窗口不该降的时候降下去。链路层重传可以挡住一部分误码,但会把时延尾巴拉长。读完应能区分: 链路质量问题、切换问题和拥塞问题,三者症状相似、处方不同。 把手机「突然卡住」一律写成 TCP 的锅,通常是还没画出当前关联的是哪一个接入、地址有没有变。
无线丢包、切换与 TCP 的交错
一次「手机上的网页卡住」至少有三条候选因果链:空口误码触发链路重传,时延尾巴变长;站点换了接入点甚至换了前缀,连接迁移或重连; 蜂窝或 Wi-Fi 的共享信道被别人占满,吞吐掉下去被拥塞控制当成瓶颈。 三条链的观测点不同:信号与重传计数、关联与地址是否变化、队列与窗口是否回落。本章的价值就是逼你先分流,再决定回到运输层还是留在无线章。
- 无线容量随位置和干扰变,不是一根标称速率的网线。
- 隐藏终端要用预约或调度,不能只靠加大功率。
- 移动性可以藏在链路、网络或运输/应用,藏的位置决定谁无感、谁必须改。
网络安全 —— 把信任补回开放网络
前七章默认分组会被如实转发。安全章把对手请进来:窃听、假冒、篡改、重放、拒绝服务。对策按目标拆开,而不是按产品名词堆砌。
密码学积木与认证
机密性靠加密:对称密码共享一把密钥,运算快,适合保护大量数据;非对称密码用公钥加密、私钥解密,或反过来做签名,适合解决密钥分发和不可否认。 实践中几乎总是「非对称握手,对称保护数据」。 完整性靠散列与消息认证码,防止「改了一个比特还能蒙混过关」;数字签名再把完整性和私钥持有者绑在一起。
认证要回答「对方是声称的那一方吗」,通常结合一次性随机数做挑战—应答,避免口令在路上明文飞,也避免重放旧报文。公钥基础设施用证书把公钥和身份绑在一起; 证书链的信任锚最终落在客户端预置的根上。 吊销、过期和错误颁发都是这套体系的真实弱点。这些积木单独都不构成系统,协议的艺术是把它们按正确顺序组合,并小心处理重放、降级和侧信道。密钥协商若被中间人掉包, 后面再强的对称加密也只是在跟对手共享机密。
安全电子邮件、TLS 与 IPsec
安全可以贴在不同层。邮件可以在应用里对正文签名或加密,不依赖运输层,邮件服务器也读不懂密文——这正是端到端邮件安全的卖点,也是网关杀毒变难的原因。 TLS 贴在运输层之上、HTTP 之下,先握手协商算法与密钥、认证服务器(有时也认证客户端),再保护应用字节流;HTTPS 就是把这层变成默认。 第 8 版对应的现实世界里,TLS 1.3 砍掉了一批过时套件、把 1-RTT 甚至恢复会话时的 0-RTT 变成主路径,并收紧了密钥派生。
IPsec 则贴在网络层,按数据报保护,对应用透明,常见于虚拟专用网。传输模式保护载荷,隧道模式把整个原数据报包起来。 无线链路自己还有链路层保护,防止隔壁桌听你的帧——但它不替代端到端的 TLS:接入点或运营商仍然可能看到解密后的下一跳流量。 选层就是在选「谁是对手、谁必须保持透明」。
运行时防护:防火墙与入侵检测
密码学解决不了「不该进来的连接进来了」。包过滤按地址、端口与标志位放行;状态检测记住连接是否合法建立,避免只看单个报文被分片或标志位游戏骗过; 应用网关还能看应用语义,代价是成为性能与可用性的新中心。 默认拒绝再列例外,比默认允许再打补丁更不容易漏。
入侵检测与防御系统用特征或异常模型抓已经穿过第一道闸门的流量。特征准但对未知攻击迟钝,异常灵敏但误报高。 拒绝服务从带宽耗尽到应用层慢速消耗都有,对策是过滤、扩容、任播分散和上游协同,很少是「再加一种加密算法」。运维视角下,安全是策略、日志、补丁与事件响应的闭环, 而不是单次部署一个盒。 读完应能画出:哪些威胁该用加密,哪些该用过滤,哪些只能靠监测和容量。
把威胁映射到机制
嗅探对机密性,伪装对认证,篡改对完整性,重放对新鲜性,洪水对可用性。 一种机制很少能覆盖整张表:TLS 挡前四类里的很大一部分,挡不住源站被打满;防火墙挡一部分不该进来的会话,看不懂加密载荷里的应用攻击;入侵检测能补视线,也会误报。 第 8 版把安全放在最后,不是因为它次要,而是因为它是横切关注点——你必须先知道明文协议在干什么,才知道加密和过滤各自盖住哪一段。
- 先写威胁模型和信任边界,再选贴在哪一层。
- 对称求快,非对称求分发与签名;真实协议几乎总是两者组合。
- 运行时防护处理「不该进来」和「已经进来之后怎么看见」,与密码学互补。