计算机网络自顶向下方法第九版学习:吞吐量与协议分层
吞吐量(Throughput) 是衡量网络性能的关键指标之一,除了时延和丢包率之外。RsR_sRs:服务器到路由器的链路速率RcR_cRc:路由器到客户端的链路速率分析(把数据流比作水流,把链路比作水管):若 Rs<RcR_s < R_cRs<Rc:服务器是瓶颈,吞吐量 = RsR_sRs若 Rc<RsR_c < R_sRc<Rs:路由器转发不过来,数据积压,吞吐量 = RcR_cR
1.4.4 计算机网络中的吞吐量
什么是吞吐量?
吞吐量(Throughput) 是衡量网络性能的关键指标之一,除了时延和丢包率之外。
- 瞬时吞吐量:某一时刻主机 B 接收文件的速率(单位:bits/sec)
- 平均吞吐量:若文件共 F F F bits,传输共花了 T T T 秒,则平均吞吐量为:
平均吞吐量 = F T (bits/sec) \text{平均吞吐量} = \frac{F}{T} \quad \text{(bits/sec)} 平均吞吐量=TF(bits/sec)
场景一:简单两链路网络(图 1.20a)
服务器 ---[Rs]--- 路由器 ---[Rc]--- 客户端
- R s R_s Rs:服务器到路由器的链路速率
- R c R_c Rc:路由器到客户端的链路速率
分析(把数据流比作水流,把链路比作水管): - 若 R s < R c R_s < R_c Rs<Rc:服务器是瓶颈,吞吐量 = R s R_s Rs
- 若 R c < R s R_c < R_s Rc<Rs:路由器转发不过来,数据积压,吞吐量 = R c R_c Rc
结论:
吞吐量 = min ( R s , R c ) \text{吞吐量} = \min(R_s, R_c) 吞吐量=min(Rs,Rc)
这条速率最慢的链路称为 瓶颈链路(Bottleneck Link)。
传输时间估算:
T = F min ( R s , R c ) T = \frac{F}{\min(R_s, R_c)} T=min(Rs,Rc)F
具体例子: - 文件大小: F = 32 × 10 6 F = 32 \times 10^6 F=32×106 bits(约 4 MB 的 MP3)
- 服务器链路: R s = 2 R_s = 2 Rs=2 Mbps
- 客户端链路: R c = 1 R_c = 1 Rc=1 Mbps
- 瓶颈在客户端,吞吐量 = 1 Mbps
T = 32 × 10 6 1 × 10 6 = 32 秒 T = \frac{32 \times 10^6}{1 \times 10^6} = 32 \text{ 秒} T=1×10632×106=32 秒
场景二:多链路网络(图 1.20b)
服务器 --[R1]-- 路由器1 --[R2]-- 路由器2 -- ... -- 路由器N --[RN]-- 客户端
N 条链路,速率分别为 R 1 , R 2 , … , R N R_1, R_2, \ldots, R_N R1,R2,…,RN,吞吐量仍然取最小值:
吞吐量 = min ( R 1 , R 2 , … , R N ) \text{吞吐量} = \min(R_1, R_2, \ldots, R_N) 吞吐量=min(R1,R2,…,RN)
核心思想:链路就像串联的水管,整体流量取决于最细的那段。
场景三:真实互联网模型(图 1.21a)
服务器 --[Rs]-- [核心网(超高速)] --[Rc]-- 客户端
现实中,互联网核心网带宽非常充裕,瓶颈通常在接入网(即用户家里的宽带):
吞吐量 = min ( R s , R c ) \text{吞吐量} = \min(R_s, R_c) 吞吐量=min(Rs,Rc)
场景四:多用户共享链路(图 1.21b)
10台服务器 --各自Rs--> [核心网] --共享链路R--> [核心网] --各自Rc--> 10台客户端
- R s = 2 R_s = 2 Rs=2 Mbps(每台服务器接入速率)
- R c = 1 R_c = 1 Rc=1 Mbps(每台客户端接入速率)
- R = 5 R = 5 R=5 Mbps(核心共享链路,被10个下载任务平分)
每个下载能分到的共享链路带宽:
R 10 = 5 Mbps 10 = 0.5 Mbps = 500 kbps \frac{R}{10} = \frac{5 \text{ Mbps}}{10} = 0.5 \text{ Mbps} = 500 \text{ kbps} 10R=105 Mbps=0.5 Mbps=500 kbps
此时 500 kbps < R c R_c Rc = 1 Mbps,瓶颈在核心共享链路:
每条连接的吞吐量 = 500 kbps \text{每条连接的吞吐量} = 500 \text{ kbps} 每条连接的吞吐量=500 kbps
结论:吞吐量不仅取决于路径上的链路速率,还受路径上其他流量的影响。
吞吐量总结对比表
| 场景 | 拓扑 | 吞吐量公式 | 瓶颈位置 |
|---|---|---|---|
| 两链路 | S–Rs–路由器–Rc–C | min ( R s , R c ) \min(R_s, R_c) min(Rs,Rc) | 较慢链路 |
| N链路 | 多跳路由 | min ( R 1 , … , R N ) \min(R_1,\ldots,R_N) min(R1,…,RN) | 最慢链路 |
| 真实互联网 | 接入+核心 | min ( R s , R c ) \min(R_s, R_c) min(Rs,Rc) | 接入网 |
| 多用户共享 | 共享核心链路 | min ( R s , R c , R / N ) \min(R_s, R_c, R/N) min(Rs,Rc,R/N) | 可能在共享链路 |
1.5 协议层次及其服务模型
1.5.1 分层架构
为什么要分层?
互联网是一个极其复杂的系统。分层架构的好处:
- 模块化:每层只关心自己的职责
- 易于维护:修改某层实现不影响其他层
- 便于讨论:可以针对某一层单独分析
航空公司类比
用坐飞机的流程来类比网络的分层:
出发机场 中间空管中心 到达机场
----------- --------------- -----------
购票(Ticket) 投诉(Ticket)
托运行李(Baggage) 取行李(Baggage)
登机口(Gate/load) 登机口(Gate/unload)
跑道起飞(Takeoff) 跑道降落(Landing)
飞机路由(Routing) <--> 飞机路由(Routing) <--> 飞机路由(Routing)
关键思想:每层只服务于上层,并依赖下层提供的服务。就像你进登机口之前,必须已经完成了购票和托运。
对应到网络中:每个协议层通过以下两种方式提供服务:
- 在本层执行特定操作
- 使用下层提供的服务
Internet 五层协议栈(图 1.24)
+---------------+
| Application | 应用层
+---------------+
| Transport | 传输层
+---------------+
| Network | 网络层
+---------------+
| Link | 链路层
+---------------+
| Physical | 物理层
+---------------+
各层详解
1. 应用层(Application Layer)
- 所在位置:端系统(你的电脑、手机)
- 主要协议:HTTP(网页)、SMTP(邮件)、DNS(域名解析)
- 数据单位:报文(Message)
- 特点:协议分布在多个端系统上,通过网络交换信息
2. 传输层 (Transport Layer)
- 职责:在应用程序端点之间传送应用层报文
- 两个主要协议:
- TCP:面向连接,提供可靠传输、流量控制、拥塞控制,将长报文拆成短段
- UDP:无连接,不可靠,无流控,无拥塞控制(但速度快,开销小)
- 数据单位:报文段(Segment)
| 特性 | TCP | UDP |
|---|---|---|
| 连接方式 | 面向连接 | 无连接 |
| 可靠性 | 保证可靠交付 | 不保证 |
| 流量控制 | 有 | 无 |
| 拥塞控制 | 有 | 无 |
| 适用场景 | 文件传输、网页 | 视频直播、DNS |
3. 网络层(Network Layer)
- 职责:将数据报(Datagram)从源主机转发到目标主机
- 核心协议:IP 协议(唯一,所有网络设备必须实现)
- 还包含:各种路由协议(决定数据报走哪条路)
- 数据单位:数据报(Datagram)
- 常被称为"IP 层",是互联网的粘合剂
4. 链路层(Link Layer)
- 职责:将数据报从一个节点(主机或路由器)传到下一个节点
- 协议举例:以太网(Ethernet)、WiFi、DOCSIS(有线电视网)
- 注意:数据报在不同链路上可能用不同链路层协议(如先走 WiFi,再走以太网)
- 数据单位:帧(Frame)
5. 物理层(Physical Layer)
- 职责:在链路上逐 bit 传输(从一个节点到相邻节点)
- 依赖具体传输介质:双绞铜线、单模光纤、同轴电缆等
- 以太网针对不同介质有不同物理层协议
1.5.2 封装(Encapsulation)
封装是分层架构的核心机制——每一层都在上层数据前面加上自己的头部信息。
封装过程(发送端)
应用层: [ M ] ← 报文 Message
传输层: [ Ht | M ] ← 加传输层头部,形成报文段 Segment
网络层: [ Hn | Ht | M ] ← 加网络层头部,形成数据报 Datagram
链路层:[ Hl | Hn | Ht | M ] ← 加链路层头部,形成帧 Frame
物理层:逐 bit 发送
解封装过程(接收端,反向)
物理层:接收 bit 流
链路层:去掉 Hl,得到 [ Hn | Ht | M ]
网络层:去掉 Hn,得到 [ Ht | M ]
传输层:去掉 Ht,得到 [ M ]
应用层:得到原始报文 M
中间设备实现的层次
不同网络设备实现的协议层数不同:
端系统(主机): 应用 / 传输 / 网络 / 链路 / 物理 (5层全部)
路由器(Router): 网络 / 链路 / 物理 (3层)
链路层交换机: 链路 / 物理 (2层)
路由器能识别 IP 地址(第3层),但链路层交换机只能识别以太网 MAC 地址(第2层)。
封装类比:公司内部信件
这个过程就像公司内部寄信:
Alice 写了一份备忘录(应用层报文 M)
→ 放入写有 Bob 姓名和部门的内部信封(传输层 Ht + M = Segment)
→ 邮件室将内部信封装入邮政信封,
写上两个分公司的地址(网络层 Hn + Segment = Datagram)
→ 邮政服务配送(链路层+物理层传输)
→ 到达后逐层拆封,Bob 收到备忘录
Mermaid:封装与传输流程图
协议分层的优缺点总结
优点:
- 结构清晰,便于理解和讨论复杂系统
- 模块化设计,修改某层不影响其他层
- 易于标准化和互操作
缺点(也有反对者): - 某些功能可能在多层重复实现(如错误恢复在链路层和传输层都有)
- 某层可能需要另一层的信息(如时间戳),违反了层间分离的原则
知识点速查
| 概念 | 说明 |
|---|---|
| 瞬时吞吐量 | 某时刻接收方的接收速率 |
| 平均吞吐量 | F / T F/T F/T,文件大小除以传输时间 |
| 瓶颈链路 | 路径中速率最慢的链路 |
| 协议栈 | 各层协议的集合 |
| 封装 | 发送时每层加头部;接收时逐层去头部 |
| 报文(Message) | 应用层数据单位 |
| 报文段(Segment) | 传输层数据单位 |
| 数据报(Datagram) | 网络层数据单位 |
| 帧(Frame) | 链路层数据单位 |
计算机网络笔记:网络安全威胁与互联网发展史
1.6 网络攻击(Networks Under Attack)
互联网已经成为现代社会的关键基础设施,企业、学校、政府机构乃至普通个人都高度依赖它。但与此同时,"坏人"也在不断尝试破坏我们的网络、侵犯我们的隐私、让我们依赖的服务瘫痪。
网络安全(Network Security) 这门学科研究的就是:
- 攻击者如何攻击网络
- 我们如何防御这些攻击
- 如何从架构设计上免疫攻击
1.6.1 恶意软件(Malware)
什么是恶意软件?
我们连接互联网是为了收发数据(视频、搜索结果、消息等),但数据里也可能夹带恶意软件(Malware),一旦感染设备,它可以:
- 删除文件
- 安装间谍软件(Spyware),窃取密码、社会安全号、键盘输入记录等
- 将你的设备加入僵尸网络(Botnet)
什么是僵尸网络(Botnet)?
攻击者(C&C 服务器)
|
_____|______
| | |
被控主机A 被控主机B 被控主机C ...(成千上万台"肉鸡")
|
统一发起攻击(发垃圾邮件 / DDoS)
被感染的主机称为 zombie(僵尸机) 或 肉鸡,攻击者统一控制它们,用于:
- 发送垃圾邮件
- 对目标发起分布式拒绝服务攻击(DDoS)
自我复制的特性
现代恶意软件大多具有自我复制能力:
感染主机A → 扫描其他主机 → 感染主机B → 感染主机C → ...
传播速度呈指数级增长,类似病毒在生物体中的扩散。
1.6.2 拒绝服务攻击(DoS / DDoS)
什么是 DoS 攻击?
拒绝服务攻击(Denial-of-Service,DoS) 让合法用户无法正常使用某个网络服务(Web服务器、邮件服务器、DNS服务器等)。
DoS 攻击主要分三类:
| 攻击类型 | 方式 | 效果 |
|---|---|---|
| 漏洞攻击(Vulnerability Attack) | 发送精心构造的少量数据包到存在漏洞的应用/系统 | 服务崩溃或主机宕机 |
| 带宽洪泛(Bandwidth Flooding) | 向目标发送海量数据包,堵塞接入链路 | 合法数据包无法到达服务器 |
| 连接洪泛(Connection Flooding) | 建立大量半开或全开的 TCP 连接 | 服务器资源耗尽,拒绝新连接 |
带宽洪泛攻击分析
设服务器接入链路速率为 R R R bps,攻击者需要发送约 R R R bps 的流量才能造成伤害。
单源 DoS 的局限:
- 若 R R R 很大,单台攻击机可能无法产生足够流量
- 单一来源容易被上游路由器识别并封锁
解决方案:分布式 DoS(DDoS)
攻击者控制多台僵尸机,让它们同时向目标发包。设攻击机数量为 N N N,每台发包速率为 r r r,只需满足:
N × r ≈ R N \times r \approx R N×r≈R
即可使目标链路瘫痪。
DDoS 攻击示意图(对应图 1.26)
攻击者(Attacker)
|
|-- "start attack" --> zombie A --|
|-- "start attack" --> zombie B --|--> 路由器 --> Victim(受害者)
|-- "start attack" --> zombie C --|
|-- "start attack" --> zombie D --|
用 Mermaid 表示:
每年约有 100 起针对互联网基础设施的重大 DDoS 攻击事件。
1.6.3 数据包嗅探(Packet Sniffing)
原理
在无线网络中,信号在空气中广播传播,任何人只要在附近放置一个被动接收器,就能接收到所有传输的数据包。这个设备叫做数据包嗅探器(Packet Sniffer)。
发送方 --------[WiFi 无线信号]------> 接收方
|
| (同时被被动接收)
v
嗅探者(Sniffer)
(记录所有数据包)
哪些环境有风险?
- 无线网络(WiFi):信号广播,任何人均可接收
- 有线广播网络(以太网 LAN):广播包可被同网段设备捕获
- 有线电视接入网:同样使用广播方式
- 机构接入路由器:若攻击者获得访问权限,可部署嗅探器
嗅探的危险性
嗅探器是被动的(不注入任何数据包),极难被检测到。被窃取的信息可能包括:
- 密码
- 社会安全号
- 商业机密
- 私人消息
防御方式
主要依靠密码学(Cryptography) 对数据加密,即使包被截获也无法读取内容(详见第8章)。
1.6.4 IP 欺骗(IP Spoofing)
原理
攻击者可以构造一个数据包,伪造源 IP 地址,让接收方(如路由器)以为数据包来自可信主机,从而执行恶意命令(如修改路由表)。
攻击者
|
| 构造数据包:
| 源IP = 可信主机IP(伪造)
| 目的IP = 目标路由器IP
| 内容 = 恶意命令
|
v
互联网(转发该包)
|
v
目标路由器(信以为真,执行命令)
这种行为称为 IP 欺骗(IP Spoofing),是"冒充可信用户"攻击的一种。
防御方式
需要端点身份认证(End-point Authentication):在通信中验证消息确实来自声称的发送方(详见第8章)。
1.6.5 为什么互联网天生不安全?
互联网最初的设计基于这样一个模型:
“一群互相信任的用户连接到一个透明网络”
在这个假设下:
- 任何用户默认可以向任何其他用户发包
- 用户身份按声明接受,不做验证
但今天的互联网用户并不互相信任。我们需要防御:
| 威胁类型 | 说明 |
|---|---|
| 数据包嗅探(Sniffing) | 被动监听窃取数据 |
| IP 欺骗(Spoofing) | 伪造身份发包 |
| 中间人攻击(Man-in-the-Middle) | 拦截并篡改通信 |
| DDoS 攻击 | 分布式拒绝服务 |
| 恶意软件(Malware) | 感染并控制设备 |
重要观念:互相信任的用户是例外,不是常态。
1.7 计算机网络与互联网的发展史
1.7.1 分组交换的诞生(1961—1972)
背景
1960年代,电话网是主导通信网络,使用电路交换(为每次通话预留固定线路)。但计算机产生的流量是突发性的(一段活动 + 一段等待),电路交换非常浪费。
分组交换的独立发明
三个研究团队几乎同时、互不知情地发明了分组交换:
| 人物 | 机构 | 贡献 |
|---|---|---|
| Leonard Kleinrock | MIT | 用排队论证明分组交换对突发流量的高效性(1961) |
| Paul Baran | 兰德研究所 | 研究军事网络安全语音传输(1964) |
| Donald Davies & Roger Scantlebury | 英国国家物理实验室 | 独立提出分组交换概念 |
ARPAnet 的诞生
1969年9月
UCLA 安装第一台分组交换机(Kleinrock 督导)
SRI、UC Santa Barbara、犹他大学相继加入
→ 年底:ARPAnet 有 4 个节点
1972年
ARPAnet 增长到约 15 个节点
Robert Kahn 公开演示
第一个主机间协议 NCP 完成
Ray Tomlinson 写出第一个电子邮件程序
1.7.2 专有网络与互联(1972—1980)
多网络的出现
ARPAnet 之外出现了多个独立的分组交换网络:
- ALOHANet:夏威夷微波网络,首个多路访问协议(Norman Abramson)
- Telenet:BBN 商业分组交换网
- Cyclades:法国分组交换网(Louis Pouzin)
- IBM SNA(1969—1974)
TCP/IP 的诞生
网络越来越多,如何把它们互联?Vinton Cerf 和 Robert Kahn 提出了 互联网络(Internetworking) 架构,这就是 TCP 的起源。
早期 TCP 将可靠传输和转发功能合在一起,后来认识到需要不可靠、无流控的传输服务(用于语音等),于是将 IP 从 TCP 中分离,UDP 也随之诞生。
到 1970 年代末,TCP、UDP、IP 三个核心协议的概念均已确立。
以太网(Ethernet) 也在此期间由 Metcalfe 和 Boggs 开发出来,用于连接 PC、打印机和共享磁盘。
1.7.3 网络大繁荣(1980—1990)
1970年代末:ARPAnet 约 200 台主机
1980年代末:公共互联网主机数达到 10 万台
主要事件
- BITNET:连接美国东北部大学,提供邮件和文件传输
- CSNET:为没有 ARPAnet 访问权的大学研究人员服务
- NSFNET(1986):连接 NSF 超级计算中心,初始骨干速率 56 kbps,十年内升至 1.5 Mbps
关键里程碑
- 1983年1月1日:ARPAnet 正式将主机协议从 NCP 切换到 TCP/IP(所有主机同一天切换,称为"旗帜日")
- 1980年代末:TCP 加入基于主机的拥塞控制(Jacobson,1988)
- DNS 开发完成,实现域名到 IP 地址的映射(如 gaia.cs.umass.edu → 32位IP)
1.7.4 互联网爆炸式增长(1990年代)
Web 的诞生
万维网(World Wide Web) 由 Tim Berners-Lee 在 CERN 于 1989—1991 年间发明,包含四个关键组件:
HTML(页面格式)
HTTP(传输协议)
Web 服务器
浏览器
1993年底约有 200 台 Web 服务器;Marc Andreessen 开发了图形界面浏览器 Mosaic,后创立 Netscape。
四大"杀手级应用"
| 应用 | 来源 |
|---|---|
| 电子邮件(含附件、Web邮件) | 研究社区 |
| Web 浏览与电子商务 | 研究社区 |
| 即时通讯(含联系人列表) | 年轻创业者 |
| P2P 文件共享(Napster,MP3) | 年轻创业者 |
互联网泡沫
1995—2001年,数百家互联网创业公司上市,估值数十亿却无盈利。2000—2001年泡沫破裂,大批公司倒闭。存活并壮大的包括:Microsoft、Cisco、Yahoo、eBay、Google、Amazon。
1.7.5 新千年(2000年代至今)
主要发展趋势
1. 宽带接入普及
家庭宽带从有线/DSL,发展到光纤入户(FTTH)、5G 固定无线、低轨卫星(LEO),催生了大量视频应用:
- YouTube、TikTok(用户生成视频)
- Netflix(高清流媒体)
- Zoom、FaceTime(多人视频会议)
2. 高速无线接入无处不在
2011年,无线设备连接互联网的数量超过有线设备。智能手机(iPhone、Android)实现随时随地上网,催生了: - 导航地图(Google Maps、Waze)
- 打车(Uber、滴滴)
- 外卖、本地搜索
3. 社交网络的崛起
Facebook、Instagram、Twitter、TikTok、微信等在互联网之上构建了巨大的人际网络,并通过 API 创造了移动支付、分布式游戏等新应用。
4. 内容提供商自建专网
Google、Microsoft 等建立了自己的私有骨干网络,直接与下级 ISP 对等互联,绕过公共互联网,提供近乎实时的服务响应。
5. 云计算
Amazon EC2、Microsoft Azure、阿里云等云平台让企业和大学可以将应用迁移到云端,享受弹性计算、存储和高性能网络。
互联网发展时间线(Mermaid)
知识点速查
| 概念 | 说明 |
|---|---|
| 恶意软件(Malware) | 感染设备、窃取数据、破坏系统的软件 |
| 僵尸网络(Botnet) | 被控制的大量感染主机集合 |
| DoS 攻击 | 使服务对合法用户不可用 |
| DDoS 攻击 | 分布式DoS,多台僵尸机同时攻击 |
| 数据包嗅探(Sniffing) | 被动接收并记录网络中的数据包 |
| IP 欺骗(IP Spoofing) | 伪造数据包源IP地址冒充可信主机 |
| ARPAnet | 互联网的前身,1969年诞生 |
| TCP/IP | 互联网核心协议,1983年成为标准 |
| WWW | 万维网,1989-1991年由Berners-Lee发明 |
| 云计算 | 将计算和存储资源作为服务通过网络提供 |
第一章总结与课后习题详解
1.8 本章总结
本章学习了什么?
第一章是整本书的"迷你课程",覆盖了计算机网络的全貌:
网络边缘
└── 端系统 & 应用程序
└── 接入网(链路技术、物理媒介)
网络核心
└── 分组交换 vs 电路交换
└── 互联网结构(ISP 层次体系)
性能指标
└── 时延(传输、传播、排队、处理)
└── 吞吐量
└── 丢包
体系结构
└── 协议分层
└── 服务模型
└── 封装
全书章节路线图
本书采用自顶向下的方式,从应用层讲起,逐层向下:
第1章 计算机网络与互联网(概论)
第2章 应用层
第3章 传输层
第4章 网络层:数据平面
第5章 网络层:控制平面
第6章 链路层与局域网
第7章 无线与移动网络
第8章 网络安全
为什么从应用层开始讲?
先理解应用(用户真正需要什么),再理解网络需要提供什么服务,最后才理解底层如何实现——逻辑最自然。
复习题详解(Review Questions)
Section 1.1
R1. 主机(host)和端系统(end system)有什么区别?
没有区别,二者是同义词。端系统包括:台式机、笔记本、智能手机、服务器、IoT设备等。Web 服务器也是端系统。
R3. 为什么协议标准很重要?
协议标准确保不同厂商、不同设备之间能够互相通信。就像人类需要共同语言一样,没有统一标准,A 厂路由器就无法和 B 厂交换机协同工作。
Section 1.3
R11. 存储转发(store-and-forward)的端到端时延
拓扑:发送方 --[R1]–> 分组交换机 --[R2]–> 接收方
存储转发要求交换机收完整个分组再转发。
d end-to-end = L R 1 + L R 2 d_{\text{end-to-end}} = \frac{L}{R_1} + \frac{L}{R_2} dend-to-end=R1L+R2L
(忽略排队、传播和处理时延)
R12. 电路交换 vs 分组交换
| 对比项 | 电路交换 | 分组交换 |
|---|---|---|
| 资源预留 | 是(独占) | 否(统计复用) |
| 延迟稳定性 | 好(固定带宽) | 差(可能排队) |
| 利用率 | 低(空闲浪费) | 高 |
| 适合场景 | 实时语音 | 数据传输 |
TDM vs FDM(均为电路交换的复用方式):
- FDM:将频段划分给各用户,每人一段频率
- TDM:将时间划分成帧,每用户轮流使用全部带宽
TDM 优势:每个用户在自己的时隙内独享全部链路带宽,数字信号处理更灵活,更易于动态分配。
R13. 分组交换与电路交换对比计算
条件:链路 2 Mbps,每用户传输速率 1 Mbps,每用户仅 20% 时间在传输。
(a) 电路交换能支持多少用户?
每用户需要 1 Mbps,总带宽 2 Mbps:
用户数 = 2 Mbps 1 Mbps = 2 人 \text{用户数} = \frac{2 \text{ Mbps}}{1 \text{ Mbps}} = 2 \text{ 人} 用户数=1 Mbps2 Mbps=2 人
(b) 分组交换:何时有排队?
- 2个或更少用户同时传输:总速率 ≤ 2 \leq 2 ≤2 Mbps,不超过链路容量,无排队
- 3个用户同时传输:总速率 = 3 = 3 =3 Mbps > 2 > 2 >2 Mbps,超出容量,产生排队
© 某用户正在传输的概率
p = 0.2 p = 0.2 p=0.2
(题目直接给出,每用户 20% 时间在传输)
(d) 三个用户同时传输的概率(二项分布)
P ( 3人同时传输 ) = ( 3 3 ) × 0.2 3 × 0.8 0 = 0.008 = 0.8 % P(\text{3人同时传输}) = \binom{3}{3} \times 0.2^3 \times 0.8^0 = 0.008 = 0.8\% P(3人同时传输)=(33)×0.23×0.80=0.008=0.8%
队列增长 = 3人同时传输的比例 = 0.8% 的时间
Section 1.4
R16. 端到端时延的组成部分
从源主机到目标主机,时延由以下四部分组成:
| 时延类型 | 公式 | 是否固定 |
|---|---|---|
| 传输时延 d trans d_{\text{trans}} dtrans | L / R L/R L/R(分组长度/链路速率) | 固定(取决于分组大小和链路速率) |
| 传播时延 d prop d_{\text{prop}} dprop | d / s d/s d/s(链路长度/传播速度) | 固定(取决于物理距离) |
| 处理时延 d proc d_{\text{proc}} dproc | 路由器检查首部、决定转发 | 基本固定(微秒级) |
| 排队时延 d queue d_{\text{queue}} dqueue | 等待前面分组发送完毕 | 可变(取决于网络拥塞) |
R18. 传播时延计算
- 分组长度: L = 1000 L = 1000 L=1000 字节 = 8000 = 8000 =8000 bits
- 链路长度: d = 2500 d = 2500 d=2500 km = 2.5 × 10 6 = 2.5 \times 10^6 =2.5×106 m
- 传播速度: s = 2.5 × 10 8 s = 2.5 \times 10^8 s=2.5×108 m/s
- 传输速率: R = 2 R = 2 R=2 Mbps
传播时延(只与距离有关,与分组大小无关):
d prop = d s = 2.5 × 10 6 2.5 × 10 8 = 0.01 s = 10 ms d_{\text{prop}} = \frac{d}{s} = \frac{2.5 \times 10^6}{2.5 \times 10^8} = 0.01 \text{ s} = 10 \text{ ms} dprop=sd=2.5×1082.5×106=0.01 s=10 ms
注意:传播时延与分组长度 L L L 无关,也与传输速率 R R R 无关。
通用公式:
d prop = d s d_{\text{prop}} = \frac{d}{s} dprop=sd
R19. 三链路吞吐量计算
R 1 = 500 R_1 = 500 R1=500 kbps, R 2 = 2 R_2 = 2 R2=2 Mbps, R 3 = 1 R_3 = 1 R3=1 Mbps
(a) 吞吐量(瓶颈链路):
吞吐量 = min ( R 1 , R 2 , R 3 ) = min ( 500 k , 2 M , 1 M ) = 500 kbps \text{吞吐量} = \min(R_1, R_2, R_3) = \min(500\text{k}, 2\text{M}, 1\text{M}) = 500 \text{ kbps} 吞吐量=min(R1,R2,R3)=min(500k,2M,1M)=500 kbps
(b) 文件大小 4MB = 4 × 10 6 × 8 = 3.2 × 10 7 4 \times 10^6 \times 8 = 3.2 \times 10^7 4×106×8=3.2×107 bits,传输时间:
T = F 吞吐量 = 3.2 × 10 7 5 × 10 5 = 64 秒 T = \frac{F}{\text{吞吐量}} = \frac{3.2 \times 10^7}{5 \times 10^5} = 64 \text{ 秒} T=吞吐量F=5×1053.2×107=64 秒
© R 2 R_2 R2 降为 100 kbps:
吞吐量 = min ( 500 k , 100 k , 1 M ) = 100 kbps \text{吞吐量} = \min(500\text{k}, 100\text{k}, 1\text{M}) = 100 \text{ kbps} 吞吐量=min(500k,100k,1M)=100 kbps
T = 3.2 × 10 7 10 5 = 320 秒 T = \frac{3.2 \times 10^7}{10^5} = 320 \text{ 秒} T=1053.2×107=320 秒
Section 1.5
R23. 五层协议栈各层职责
| 层次 | 名称 | 主要职责 | 数据单位 |
|---|---|---|---|
| 5 | 应用层 | 支持网络应用(HTTP/SMTP/DNS) | 报文 Message |
| 4 | 传输层 | 端到端数据传输(TCP/UDP) | 报文段 Segment |
| 3 | 网络层 | 源到目标的路由转发(IP) | 数据报 Datagram |
| 2 | 链路层 | 相邻节点间帧传输(Ethernet/WiFi) | 帧 Frame |
| 1 | 物理层 | 逐比特传输 | 比特 Bit |
R25. 各设备处理哪些层?
端系统(主机): 第1~5层(全部)
路由器: 第1~3层(物理、链路、网络)
链路层交换机: 第1~2层(物理、链路)
路由器能读 IP 地址(第3层),交换机只能读 MAC 地址(第2层)。
课后计算题详解(Problems)
P2. 存储转发多跳时延推广
原始公式(1个分组,N条链路,速率均为 R):
d = N ⋅ L R d = N \cdot \frac{L}{R} d=N⋅RL
推广:P 个分组背靠背发送,经 N 条链路:
分析过程(流水线效应):
时间轴(N=3条链路,P=3个分组):
链路1 链路2 链路3
t=L/R pkt1完 - -
t=2L/R pkt2完 pkt1完 -
t=3L/R pkt3完 pkt2完 pkt1完
t=4L/R - pkt3完 pkt2完
t=5L/R - - pkt3完
第一个分组到达终点需要 N ⋅ L R N \cdot \frac{L}{R} N⋅RL,之后每隔 L R \frac{L}{R} RL 到达一个分组,共 P 个:
d total = ( N + P − 1 ) ⋅ L R d_{\text{total}} = (N + P - 1) \cdot \frac{L}{R} dtotal=(N+P−1)⋅RL
P6. 传播时延与传输时延基础题
设:链路速率 R R R bps,链路长度 m m m 米,传播速度 s s s m/s,分组大小 L L L bits
(a) 传播时延:
d prop = m s d_{\text{prop}} = \frac{m}{s} dprop=sm
(b) 传输时延:
d trans = L R d_{\text{trans}} = \frac{L}{R} dtrans=RL
© 端到端时延(忽略处理和排队):
d end-to-end = d trans + d prop = L R + m s d_{\text{end-to-end}} = d_{\text{trans}} + d_{\text{prop}} = \frac{L}{R} + \frac{m}{s} dend-to-end=dtrans+dprop=RL+sm
(d) t = d trans t = d_{\text{trans}} t=dtrans 时,最后一个 bit 在哪里?
t = d trans t = d_{\text{trans}} t=dtrans 是发送方刚把最后一个 bit 发出的时刻。此时最后一个 bit 刚离开发送方,正在链路的起点。
(e) 若 d prop > d trans d_{\text{prop}} > d_{\text{trans}} dprop>dtrans,在 t = d trans t = d_{\text{trans}} t=dtrans 时第一个 bit 在哪里?
第一个 bit 在 t = 0 t=0 t=0 发出,已经在链路上传播了 d trans d_{\text{trans}} dtrans 秒,走了 s ⋅ d trans s \cdot d_{\text{trans}} s⋅dtrans 米:
距发送方 = s ⋅ d trans = s ⋅ L R 米 \text{距发送方} = s \cdot d_{\text{trans}} = s \cdot \frac{L}{R} \text{ 米} 距发送方=s⋅dtrans=s⋅RL 米
因为 d prop > d trans d_{\text{prop}} > d_{\text{trans}} dprop>dtrans,即 m s > L R \frac{m}{s} > \frac{L}{R} sm>RL,所以 s ⋅ L R < m s \cdot \frac{L}{R} < m s⋅RL<m,说明第一个 bit 还未到达接收方,仍在链路中间。
(f) 若 d prop < d trans d_{\text{prop}} < d_{\text{trans}} dprop<dtrans,在 t = d trans t = d_{\text{trans}} t=dtrans 时第一个 bit 在哪里?
第一个 bit 已到达接收方(因为 d prop < d trans d_{\text{prop}} < d_{\text{trans}} dprop<dtrans,即传播比传输快)。
(g) 求使 d prop = d trans d_{\text{prop}} = d_{\text{trans}} dprop=dtrans 的距离 m m m:
已知: s = 2.5 × 10 8 s = 2.5 \times 10^8 s=2.5×108 m/s, L = 1500 L = 1500 L=1500 字节 = 12000 = 12000 =12000 bits, R = 10 R = 10 R=10 Mbps
m s = L R \frac{m}{s} = \frac{L}{R} sm=RL
m = s ⋅ L R = 2.5 × 10 8 × 12000 10 7 = 2.5 × 10 8 × 1.2 × 10 − 3 = 300000 m = 300 km m = s \cdot \frac{L}{R} = 2.5 \times 10^8 \times \frac{12000}{10^7} = 2.5 \times 10^8 \times 1.2 \times 10^{-3} = 300000 \text{ m} = 300 \text{ km} m=s⋅RL=2.5×108×10712000=2.5×108×1.2×10−3=300000 m=300 km
P8. 分组交换二项分布概率计算
条件:链路 10 Mbps,每用户需 200 kbps,每用户传输概率 p = 0.1 p = 0.1 p=0.1,共 120 用户。
(a) 电路交换最多支持多少用户?
10 Mbps 200 kbps = 50 人 \frac{10 \text{ Mbps}}{200 \text{ kbps}} = 50 \text{ 人} 200 kbps10 Mbps=50 人
(b) 某用户正在传输的概率:
p = 0.1 p = 0.1 p=0.1
© 恰好 n 个用户同时传输(二项分布):
P ( X = n ) = ( 120 n ) × 0.1 n × 0.9 120 − n P(X = n) = \binom{120}{n} \times 0.1^n \times 0.9^{120-n} P(X=n)=(n120)×0.1n×0.9120−n
(d) 51 个或更多用户同时传输的概率:
链路容量为 50 个用户( 50 × 200 = 10000 50 \times 200 = 10000 50×200=10000 kbps),超过 50 个就拥塞:
P ( X ≥ 51 ) = ∑ n = 51 120 ( 120 n ) × 0.1 n × 0.9 120 − n P(X \geq 51) = \sum_{n=51}^{120} \binom{120}{n} \times 0.1^n \times 0.9^{120-n} P(X≥51)=n=51∑120(n120)×0.1n×0.9120−n
这个值极小(远小于 0.0001),说明分组交换在这种场景下几乎不会拥塞,却能支持 120 用户(远超电路交换的 50 用户)。
下面给出 C++ 计算代码:
#include <iostream>
#include <cmath>
#include <vector>
// 计算组合数 C(n, k),使用对数防止溢出
double log_combination(int n, int k) {
double result = 0.0;
for (int i = 0; i < k; i++) {
result += std::log(n - i) - std::log(i + 1);
}
return result;
}
// 计算二项分布 P(X = k),n次独立试验,成功概率p
double binomial_prob(int n, int k, double p) {
double log_prob = log_combination(n, k)
+ k * std::log(p)
+ (n - k) * std::log(1.0 - p);
return std::exp(log_prob);
}
int main() {
int n = 120; // 用户总数
double p = 0.1; // 每用户传输概率
int capacity = 50; // 链路最大并发用户数
// 计算 P(X >= 51),即拥塞概率
double prob_congestion = 0.0;
for (int k = capacity + 1; k <= n; k++) {
prob_congestion += binomial_prob(n, k, p);
}
std::cout << "用户总数 n = " << n << std::endl;
std::cout << "传输概率 p = " << p << std::endl;
std::cout << "链路容量(最大并发用户)= " << capacity << std::endl;
std::cout << "拥塞概率 P(X >= 51) = " << prob_congestion << std::endl;
return 0;
}
运行结果约为:拥塞概率 ≈ 1.37 × 10 − 11 \approx 1.37 \times 10^{-11} ≈1.37×10−11,几乎为零。
P10. 三链路端到端时延完整计算
通用公式(3条链路,2个分组交换机):
d end-to-end = ∑ i = 1 3 L R i + ∑ i = 1 3 d i s i + 2 ⋅ d proc d_{\text{end-to-end}} = \sum_{i=1}^{3} \frac{L}{R_i} + \sum_{i=1}^{3} \frac{d_i}{s_i} + 2 \cdot d_{\text{proc}} dend-to-end=i=1∑3RiL+i=1∑3sidi+2⋅dproc
其中:
- L R i \frac{L}{R_i} RiL:第 i i i 条链路上的传输时延
- d i s i \frac{d_i}{s_i} sidi:第 i i i 条链路上的传播时延
- d proc d_{\text{proc}} dproc:每个路由器的处理时延(共2个路由器)
代入具体数值: - L = 1500 L = 1500 L=1500 字节 = 12000 = 12000 =12000 bits
- s = 2.5 × 10 8 s = 2.5 \times 10^8 s=2.5×108 m/s(三条链路相同)
- R = 2.5 R = 2.5 R=2.5 Mbps(三条链路相同)
- d proc = 3 d_{\text{proc}} = 3 dproc=3 ms
- d 1 = 5000 d_1 = 5000 d1=5000 km, d 2 = 4000 d_2 = 4000 d2=4000 km, d 3 = 1000 d_3 = 1000 d3=1000 km
传输时延(三条链路相同):
3 × 12000 2.5 × 10 6 = 3 × 4.8 ms = 14.4 ms 3 \times \frac{12000}{2.5 \times 10^6} = 3 \times 4.8 \text{ ms} = 14.4 \text{ ms} 3×2.5×10612000=3×4.8 ms=14.4 ms
传播时延:
( 5000 + 4000 + 1000 ) × 10 3 2.5 × 10 8 = 10 7 2.5 × 10 8 = 0.04 s = 40 ms \frac{(5000 + 4000 + 1000) \times 10^3}{2.5 \times 10^8} = \frac{10^7}{2.5 \times 10^8} = 0.04 \text{ s} = 40 \text{ ms} 2.5×108(5000+4000+1000)×103=2.5×108107=0.04 s=40 ms
处理时延(2个路由器):
2 × 3 = 6 ms 2 \times 3 = 6 \text{ ms} 2×3=6 ms
总时延:
d total = 14.4 + 40 + 6 = 60.4 ms d_{\text{total}} = 14.4 + 40 + 6 = 60.4 \text{ ms} dtotal=14.4+40+6=60.4 ms
P13. 排队时延分析
(a) N 个分组同时到达空链路:
第 k k k 个分组( k = 0 , 1 , … , N − 1 k = 0, 1, \ldots, N-1 k=0,1,…,N−1)到达时,前面有 k k k 个分组等待:
d queue ( k ) = k ⋅ L R d_{\text{queue}}(k) = k \cdot \frac{L}{R} dqueue(k)=k⋅RL
平均排队时延:
d ˉ queue = 1 N ∑ k = 0 N − 1 k ⋅ L R = L R ⋅ N − 1 2 \bar{d}_{\text{queue}} = \frac{1}{N} \sum_{k=0}^{N-1} k \cdot \frac{L}{R} = \frac{L}{R} \cdot \frac{N-1}{2} dˉqueue=N1k=0∑N−1k⋅RL=RL⋅2N−1
(b) 每隔 L N / R LN/R LN/R 秒到达一批 N 个分组:
每批分组的到达间隔恰好等于发送完一批所需的时间( N × L / R N \times L/R N×L/R),所以每批都能在下一批到达前发送完,系统处于周期性稳定状态,平均排队时延仍为:
d ˉ queue = L ( N − 1 ) 2 R \bar{d}_{\text{queue}} = \frac{L(N-1)}{2R} dˉqueue=2RL(N−1)
P19. Metcalfe 定律验证
网络中有 n n n 个用户,每人向其他所有人发一条消息:
消息总数 = n × ( n − 1 ) = n 2 − n ≈ n 2 ( 当 n 很大时 ) \text{消息总数} = n \times (n-1) = n^2 - n \approx n^2 \quad (\text{当 } n \text{ 很大时}) 消息总数=n×(n−1)=n2−n≈n2(当 n 很大时)
Metcalfe 定律:网络价值 ∝ n 2 \propto n^2 ∝n2,与上面的消息数 n ( n − 1 ) ≈ n 2 n(n-1) \approx n^2 n(n−1)≈n2 一致,得到验证。
P20. M 个客户端-服务器对的吞吐量
在图 1.21(b) 的基础上,改为 M 对客户端-服务器,共享核心链路速率为 R:
每条连接能从共享链路获得: R / M R/M R/M
每条连接的端到端吞吐量取瓶颈:
吞吐量 = min ( R s , R c , R M ) \text{吞吐量} = \min\left(R_s,\ R_c,\ \frac{R}{M}\right) 吞吐量=min(Rs, Rc, MR)
P23. 分组间到达间隔(背靠背发送)
拓扑:服务器 --[ R s R_s Rs]–> 路由器 --[ R c R_c Rc]–> 客户端
已知 R s R_s Rs 是瓶颈,即 R s < R c R_s < R_c Rs<Rc。
(a) 分组到达间隔时间:
两个分组背靠背从服务器发出,间隔 L / R s L/R_s L/Rs(第一个分组发完,第二个紧跟着发)。
由于 R s < R c R_s < R_c Rs<Rc,第二条链路速度更快,不会在路由器积压,分组到达客户端的间隔依然是:
Δ t = L R s \Delta t = \frac{L}{R_s} Δt=RsL
(b) 若 R c < R s R_c < R_s Rc<Rs(第二条链路是瓶颈):
路由器收完第一个分组时,以 R c < R s R_c < R_s Rc<Rs 的速率转发,此时服务器以 R s R_s Rs 速率发第二个分组,第二个分组可能在路由器输入队列等待。
为避免排队,服务器需要延迟 T T T 秒再发第二个分组,使得第二个分组到达路由器时,第一个已经发送完毕:
T ≥ L R c − L R s = L ( 1 R c − 1 R s ) T \geq \frac{L}{R_c} - \frac{L}{R_s} = L\left(\frac{1}{R_c} - \frac{1}{R_s}\right) T≥RcL−RsL=L(Rc1−Rs1)
P24. 大文件传输:网络 vs 快递
文件大小:50 TB = 50 × 10 12 × 8 = 4 × 10 14 = 50 \times 10^{12} \times 8 = 4 \times 10^{14} =50×1012×8=4×1014 bits
网络传输时间(100 Mbps 专线):
T = 4 × 10 14 10 8 = 4 × 10 6 s ≈ 46 天 T = \frac{4 \times 10^{14}}{10^8} = 4 \times 10^6 \text{ s} \approx 46 \text{ 天} T=1084×1014=4×106 s≈46 天
FedEx 隔夜快递:约 1 天。
结论:应该选择 FedEx!
这个例子说明:对于超大数据量,物理快递的"带宽"(硬盘容量/运输时间)远超网络带宽。这也是为什么 AWS Snowball 等物理数据迁移服务存在的原因。
P25. 带宽时延积(Bandwidth-Delay Product)
条件: R = 5 R = 5 R=5 Mbps, m = 20000 m = 20000 m=20000 km = 2 × 10 7 = 2 \times 10^7 =2×107 m, s = 2.5 × 10 8 s = 2.5 \times 10^8 s=2.5×108 m/s
(a) 带宽时延积:
BDP = R × d prop = R × m s = 5 × 10 6 × 2 × 10 7 2.5 × 10 8 = 5 × 10 6 × 0.08 = 4 × 10 5 bits \text{BDP} = R \times d_{\text{prop}} = R \times \frac{m}{s} = 5 \times 10^6 \times \frac{2 \times 10^7}{2.5 \times 10^8} = 5 \times 10^6 \times 0.08 = 4 \times 10^5 \text{ bits} BDP=R×dprop=R×sm=5×106×2.5×1082×107=5×106×0.08=4×105 bits
(b) 文件 800,000 bits,链路上最多同时存在多少 bits?
等于带宽时延积(链路就像一根管道,管子容量 = 带宽 × 时延):
最多 = min ( F , BDP ) = min ( 800000 , 400000 ) = 400000 bits \text{最多} = \min(F,\ \text{BDP}) = \min(800000,\ 400000) = 400000 \text{ bits} 最多=min(F, BDP)=min(800000, 400000)=400000 bits
© 带宽时延积的物理含义:
它表示链路"在途中"能容纳的最大比特数。就像一段管道能装多少水一样,是链路的"容积"。
(d) 1 个 bit 的长度(米):
bit宽度 = s R = 2.5 × 10 8 5 × 10 6 = 50 m \text{bit宽度} = \frac{s}{R} = \frac{2.5 \times 10^8}{5 \times 10^6} = 50 \text{ m} bit宽度=Rs=5×1062.5×108=50 m
比一个足球场(约 100 m)短,但已经非常长了!
(e) 通用公式:
bit宽度 = s ⋅ 1 R = s R (米/比特) \text{bit宽度} = \frac{s \cdot 1}{R} = \frac{s}{R} \quad \text{(米/比特)} bit宽度=Rs⋅1=Rs(米/比特)
更直观地:链路总长 m m m 米,可以放 R ⋅ m / s = BDP R \cdot m / s = \text{BDP} R⋅m/s=BDP 个比特,每个比特占 m / BDP = s / R m / \text{BDP} = s/R m/BDP=s/R 米。
P31. 报文分段(Message Segmentation)
条件:文件 10 6 10^6 106 bits,链路 5 Mbps,2个交换机(即3段链路)
(a) 不分段,整体发送:
每段链路传输时延:
10 6 5 × 10 6 = 0.2 s \frac{10^6}{5 \times 10^6} = 0.2 \text{ s} 5×106106=0.2 s
存储转发,共3段:
d total = 3 × 0.2 = 0.6 s d_{\text{total}} = 3 \times 0.2 = 0.6 \text{ s} dtotal=3×0.2=0.6 s
(b) 分成 100 个分组,每个 10,000 bits:
每个分组在一段链路上的传输时延:
10000 5 × 10 6 = 0.002 s = 2 ms \frac{10000}{5 \times 10^6} = 0.002 \text{ s} = 2 \text{ ms} 5×10610000=0.002 s=2 ms
第一个分组到达第一个交换机:2 ms
第一个分组到达目的地(3段): 3 × 2 = 6 3 \times 2 = 6 3×2=6 ms
之后每隔 2 ms 到达一个分组,共 100 个分组,最后一个到达:
d total = ( 3 + 100 − 1 ) × 2 ms = 102 × 2 = 204 ms = 0.204 s d_{\text{total}} = (3 + 100 - 1) \times 2 \text{ ms} = 102 \times 2 = 204 \text{ ms} = 0.204 \text{ s} dtotal=(3+100−1)×2 ms=102×2=204 ms=0.204 s
与 P2 中的公式 ( N + P − 1 ) ⋅ L R (N + P - 1) \cdot \frac{L}{R} (N+P−1)⋅RL 一致: N = 3 , P = 100 , L / R = 2 ms N=3, P=100, L/R=2\text{ms} N=3,P=100,L/R=2ms。
© 对比:
| 方式 | 总时延 |
|---|---|
| 不分段 | 600 ms |
| 分成100段 | 204 ms |
分段后时延降低约 3倍!这就是流水线(pipeline)效应的威力。
(d) 分段的其他优点:
- 某个分组丢失只需重传那一个,不用重传整个文件
- 不同分组可走不同路径,实现负载均衡
- 单个大报文会占用链路很长时间,分段后更公平地共享网络
(e) 分段的缺点: - 每个分组都有头部开销(额外字节)
- 接收端需要重组,增加复杂度
- 分组可能乱序到达,处理更麻烦
P33. 最优分组大小
文件 F F F bits,3条链路,2个交换机,每个分组 S S S bits 数据 + 80 bits 头部,链路速率 R R R bps。
分组总大小: L = S + 80 L = S + 80 L=S+80 bits
分组总数: ⌈ F / S ⌉ ≈ F / S \lceil F/S \rceil \approx F/S ⌈F/S⌉≈F/S(假设整除)
根据流水线公式,总时延(忽略传播时延):
d = ( N + P − 1 ) ⋅ L R = ( 3 + F S − 1 ) ⋅ S + 80 R d = (N + P - 1) \cdot \frac{L}{R} = \left(3 + \frac{F}{S} - 1\right) \cdot \frac{S + 80}{R} d=(N+P−1)⋅RL=(3+SF−1)⋅RS+80
d = 1 R ( 2 ( S + 80 ) + F ( S + 80 ) S ) = 1 R ( 2 S + 160 + F + 80 F S ) d = \frac{1}{R} \left(2(S+80) + \frac{F(S+80)}{S}\right) = \frac{1}{R}\left(2S + 160 + F + \frac{80F}{S}\right) d=R1(2(S+80)+SF(S+80))=R1(2S+160+F+S80F)
对 S S S 求导并令导数为零:
d d d S = 1 R ( 2 − 80 F S 2 ) = 0 \frac{dd}{dS} = \frac{1}{R}\left(2 - \frac{80F}{S^2}\right) = 0 dSdd=R1(2−S280F)=0
S 2 = 80 F 2 = 40 F S^2 = \frac{80F}{2} = 40F S2=280F=40F
S ∗ = 40 F = 2 10 F S^* = \sqrt{40F} = 2\sqrt{10F} S∗=40F=210F
最优分组数据大小 S ∗ = 40 F S^* = \sqrt{40F} S∗=40F bits。
例如 F = 10 6 F = 10^6 F=106 bits: S ∗ = 40 × 10 6 ≈ 6325 S^* = \sqrt{40 \times 10^6} \approx 6325 S∗=40×106≈6325 bits ≈ 791 \approx 791 ≈791 字节,与实际 TCP/IP 常见的分组大小量级相近。
知识体系总览
Wireshark 实验室 与 互联网先驱访谈
一、Wireshark 实验室
1. 为什么要做 Wireshark 实验?
教材引用了一句中国谚语:
“告诉我,我会忘记;给我看,我会记住;让我参与,我才能真正理解。”
学习网络协议最好的方式不是死记硬背,而是亲眼看到协议在真实网络中运行。Wireshark 实验就是让你把课本上学的东西和现实网络对应起来。
2. 什么是分组嗅探器(Packet Sniffer)?
分组嗅探器就像给网络装了一个"录音机"——它被动地复制(嗅探)你的电脑收发的所有网络数据包,并把每个数据包的各层协议字段详细展示出来。
你的电脑
|
|--- 发出数据包 -----> 互联网
|
+---> [Wireshark 嗅探器]
|
| 复制一份,不影响正常通信
|
v
展示给你看:
- 源IP / 目标IP
- 协议类型(HTTP/TCP/UDP...)
- 每一层的头部字段
- 原始十六进制内容
关键特点:被动(passive),只"看"不"改",不会干扰正常通信。
3. Wireshark 界面详解(图 1.29)
Wireshark 界面分为四个主要区域:
+--------------------------------------------------+
| 菜单栏(Command menus) |
| File Edit View Go Capture Analyze Statistics... |
+--------------------------------------------------+
| 显示过滤器(Display filter specification) |
| [输入框:如 http、tcp、ip.addr==192.168.1.1] |
+--------------------------------------------------+
| 捕获分组列表(Listing of captured packets) |
| No. | Time | Source | Destination | Protocol |
| 56 | 11.6 | 192.168.1.128 | 128.119... | HTTP | <- 选中行(蓝色高亮)
| 57 | 11.7 | 128.119... | 192.168... | TCP |
+--------------------------------------------------+
| 选中分组的详情(Details of selected packet) |
| > Frame 56: 1182 bytes |
| > Ethernet II, Src: Apple_c2:67:53 ... |
| > Internet Protocol Version 4, Src: 192.168... |
| > 0100 .... = Version: 4 |
| > .... 0101 = Header Length: 20 bytes |
| > Total Length: 1160 |
| > Time to Live: 64 |
| > Protocol: TCP (6) |
| > Hypertext Transfer Protocol |
| GET /wireshark-labs/INTRO-wireshark-file1.html|
+--------------------------------------------------+
| 原始内容(Packet content in hex and ASCII) |
| 0000 47 45 54 20 2f 77 69 72... GET /wir |
| 0010 65 73 68 61 72 6b 2d 6c... eshark-l |
+--------------------------------------------------+
各区域作用说明
区域一:菜单栏
Capture:开始/停止抓包,选择网卡Analyze:协议分析工具Statistics:统计信息(流量图、协议分布等)
区域二:显示过滤器- 可以输入过滤表达式,只显示感兴趣的包
- 常用示例:
http:只显示 HTTP 包tcp.port == 80:只显示 80 端口的 TCP 包ip.addr == 192.168.1.1:只显示特定 IP 的包
区域三:分组列表
- 每一行是一个捕获到的数据包
- 列含义:序号、时间戳、源地址、目标地址、协议、长度、摘要信息
- 图中第 56 行(蓝色高亮)是一个 HTTP GET 请求
区域四:分组详情(树状展开,对应协议栈各层)
Frame 56(物理层信息:帧大小)
└── Ethernet II(链路层:MAC地址)
└── Internet Protocol v4(网络层:IP地址、TTL)
└── TCP(传输层:端口号、序列号)
└── HTTP(应用层:GET请求内容)
这正好对应我们学过的五层协议栈!每层都有自己的头部信息。
区域五:原始十六进制 + ASCII
- 左边是十六进制,右边是对应的 ASCII 字符
- 例如
47 45 54 20对应 ASCII 的GET——这正是 HTTP GET 请求的开头
4. 从 Wireshark 截图读懂一次 HTTP 请求
图中选中的第 56 号包就是浏览器发给服务器的 HTTP GET 请求,完整流程如下:
从第 56 号包的详情可以读出:
- 源 IP:
192.168.1.128(你的电脑) - 目标 IP:
128.119.245.12(gaia.cs.umass.edu 服务器) - 协议:HTTP,方法是 GET
- 请求的文件:
/wireshark-labs/INTRO-wireshark-file1.html
5. Wireshark 实验的意义
Wireshark 实验贯穿整本书的各章节,你将会用它观察:
| 章节 | 观察内容 |
|---|---|
| 第2章 应用层 | HTTP 请求/响应、DNS 查询 |
| 第3章 传输层 | TCP 三次握手、拥塞控制窗口变化 |
| 第4章 网络层 | IP 首部字段、TTL 递减 |
| 第5章 路由 | OSPF/BGP 路由消息 |
| 第6章 链路层 | ARP 地址解析、以太网帧结构 |
二、人物访谈:Leonard Kleinrock——互联网之父之一
人物简介
Leonard Kleinrock 是加州大学洛杉矶分校(UCLA)计算机科学杰出教授。
- 1961 年:创立了分组交换的数学理论(这是互联网技术的基础)
- 1969 年:他在 UCLA 的计算机成为互联网(ARPANET)的第一个节点
- 从该节点发出了互联网历史上的第一条消息
为什么选择研究网络?
1959 年,Kleinrock 在 MIT 读博士时,观察到大多数同学都在研究信息论和编码理论(Claude Shannon 创立的领域)。他判断 Shannon 已经解决了大部分重要问题,剩余的问题又难又意义不大。
于是他决定开辟一个全新领域:当时 MIT 周围有很多计算机,他意识到这些机器迟早需要互相通信,但当时没有有效的方式。他决定为此创建数学理论。
选择研究方向的逻辑:
已有人做且接近饱和 → 换赛道
未有人做且需求明显 → 抢先进入
发送互联网第一条消息的故事
1969 年,Kleinrock 团队尝试从 UCLA 远程登录到斯坦福研究院(SRI)的计算机,操作步骤是输入 login:
Kleinrock 团队输入:L → SRI收到:L (正常)
o → SRI收到:o (正常)
g → SRI主机崩溃!
所以互联网历史上发出的第一条消息是:“Lo”
Kleinrock 后来笑称:这是最简洁、最有预言性的消息——“Lo and behold”(你看哪!)
对比历史上其他著名第一句话:
| 发明者 | 发明 | 第一句话 |
|---|---|---|
| Samuel Morse | 电报 | “What hath God wrought.” |
| Alexander Graham Bell | 电话 | “Watson, come here! I want you.” |
| Neil Armstrong | 登月 | “That’s one small step for a man…” |
| Kleinrock | 互联网 | “Lo”(意外的) |
他的预言:1969 年已预见今天的互联网
在 ARPANET 第一个节点建立前几个月,Kleinrock 在 UCLA 新闻稿中说:
“计算机网络现在还处于婴儿期。但随着它们成长和成熟,我们很可能会看到’计算机公用事业’的普及,就像现在的电力和电话公用事业一样,为全国各地的家庭和办公室提供服务。”
他预见到了: 互联网无处不在、始终在线、任何人用任何设备在任何地点随时接入。
他没有预见到的: 社交网络的兴起——他从未想到他 99 岁的母亲和 5 岁的孙女会同时上网!
对未来网络的愿景
Kleinrock 描述了他所称的"隐形互联网(Invisible Internet)":
未来的智能空间:
桌子、墙壁、车辆、手表、腰带、手指甲、身体
|
| 嵌入传感器、执行器、摄像头、麦克风、处理器
|
v
环境感知你的存在
|
v
你用自然语言、手势、触觉,甚至脑机接口与环境交互
|
v
回应呈现在墙面显示、眼镜、全息图、语音中
他还预见了:
- 智能软件代理:在网络上挖掘数据、自适应执行任务
- 区块链技术:提供不可篡改的分布式账本
- 机器生成的流量:未来流量主要不是人产生的,而是嵌入设备和软件代理产生的
- 生成式 AI:他特别提到了当前 AI 技术的爆发式发展,认为这是下一代人的巨大机遇
给学生的建议
“互联网及其所带来的一切是一片广阔的新疆界,充满了令人惊叹的挑战。这里有巨大的创新空间。不要被今天的技术所束缚。勇于想象未来可能是什么样子,然后让它成为现实。”
三、本章知识体系总览
四、Wireshark 过滤器速查表
在第二章学习 HTTP 后你会用到这些过滤器:
| 过滤表达式 | 含义 |
|---|---|
http |
只显示 HTTP 包 |
tcp |
只显示 TCP 包 |
udp |
只显示 UDP 包 |
dns |
只显示 DNS 包 |
ip.addr == x.x.x.x |
只显示某 IP 的包 |
tcp.port == 80 |
只显示 80 端口的包 |
http.request.method == "GET" |
只显示 HTTP GET 请求 |
frame.len > 1000 |
只显示大于 1000 字节的帧 |
!(arp or dns) |
排除 ARP 和 DNS 包 |
五、第一章完整知识脉络回顾
第一章 = 整本书的预览(Mini-course)
边缘(End)
端系统:PC、手机、服务器、IoT
应用:HTTP、SMTP、P2P、流媒体
接入:DSL、HFC、FTTH、WiFi、4G/5G
核心(Core)
分组交换:存储转发、排队、统计复用
电路交换:FDM、TDM、资源预留
ISP网络:Tier-1、Tier-2、Tier-3、IXP
性能(Performance)
时延 = d_trans + d_prop + d_queue + d_proc
吞吐量 = min(所有链路速率) = 瓶颈链路
丢包 = 队列溢出
架构(Architecture)
五层协议栈:应用/传输/网络/链路/物理
封装:M → Ht+M → Hn+Ht+M → Hl+Hn+Ht+M
设备:主机(5层) 路由器(3层) 交换机(2层)
工具(Tool)
Wireshark:真实抓包,观察协议运行
第二章:应用层(Application Layer)
2.0 引言:为什么从应用层开始?
网络应用是计算机网络存在的根本原因(法语 raison d’être)。没有应用,就没有建设网络基础设施的必要。
互联网应用的发展历程
1970s-1980s 文本时代
└── 电子邮件、远程登录(Telnet)、文件传输(FTP)、新闻组
1990s 中期 Web 爆炸
└── 万维网(WWW)、搜索引擎、电子商务
2000s 至今 富媒体与社交
└── 视频会议(Zoom/FaceTime/Teams)
└── 用户生成视频(YouTube)
└── 流媒体(Netflix)
└── 在线游戏(World of Warcraft)
└── 社交网络(TikTok/Facebook/Instagram/X)
2010s 移动时代
└── 位置服务(Yelp/Waze/Tinder)
└── 移动支付(WeChat Pay/Apple Pay)
└── 即时通讯(WhatsApp/WeChat)
第二章学习什么?
- 应用层核心概念:客户端/服务器、进程、套接字
- 具体应用:Web(HTTP)、电子邮件、DNS、视频流
- 网络编程:Socket 编程(TCP 和 UDP)
2.1 网络应用的原理
核心思想:只在端系统上写代码
开发网络应用,你只需要给端系统(用户的电脑、服务器)写程序,不需要也不能给路由器、交换机这些网络核心设备写程序。
正确的思维模型:
[你的浏览器程序] <---互联网---> [Web 服务器程序]
端系统 端系统
(你写这里) (你写这里)
路由器、交换机不需要你写,它们只处理网络层及以下
为什么这样设计好? 把复杂性放在边缘(端系统),网络核心保持简单,这使得新应用可以被快速开发和部署,不需要修改网络基础设施。
2.1.1 网络应用的体系结构
注意区分两个"架构":
- 网络架构(第一章学的五层协议栈):固定的,开发者无法改变
- 应用架构:由应用开发者设计,决定应用如何分布在各端系统上
现代网络应用有两种主流架构:客户端-服务器 和 P2P。
客户端-服务器架构(Client-Server)
服务器(永远在线,固定IP)
+-----------+
| Web服务 |
| 数据中心 |
+-----------+
/ | \
/ | \
/ | \
客户端A 客户端B 客户端C
(浏览器) (手机) (平板)
特点:
- 客户端之间不直接通信(两个浏览器不直接对话)
- 服务器有固定的、众所周知的 IP 地址
- 服务器永远在线,随时响应请求
数据中心的必要性:
单台服务器撑不住大量请求(比如 Google 一天处理数十亿次搜索),所以需要数据中心——里面有成千上万台服务器,对外表现为一个"超级服务器"。
主要的大型客户端-服务器应用:
| 应用 | 服务提供商 |
|---|---|
| 生成式 AI | OpenAI、Google、Anthropic |
| 搜索 | Google、Bing、Baidu |
| 电商 | Amazon、Alibaba |
| 网页邮件 | Gmail、Yahoo Mail |
| 社交媒体 | TikTok、Facebook、WeChat |
P2P 架构(Peer-to-Peer,点对点)
P2P 网络(以 BitTorrent 为例):
用户A <-----> 用户B
^ \ / ^
| \ / |
| X |
| / \ |
v / \ v
用户C <-----> 用户D
特点:
- 没有(或很少有)专用服务器
- 每个节点(peer)既是客户端也是服务器
- 节点是普通用户的电脑,不是数据中心
P2P 最大优势:自扩展性(Self-scalability)
这是一个非常巧妙的设计:
每增加一个用户 ⇒ 既增加了需求(下载),也增加了供给(上传) \text{每增加一个用户} \Rightarrow \text{既增加了需求(下载),也增加了供给(上传)} 每增加一个用户⇒既增加了需求(下载),也增加了供给(上传)
用户越多,整个系统的服务能力也越强,系统自动扩展,不需要建更多服务器。
P2P 对比客户端-服务器:
| 对比项 | 客户端-服务器 | P2P |
|---|---|---|
| 专用服务器 | 需要(数据中心) | 不需要 |
| 成本 | 高(服务器+带宽) | 低 |
| 扩展性 | 需要增加服务器 | 自动扩展 |
| 可靠性 | 高(专业维护) | 低(节点随时下线) |
| 安全性 | 较好 | 差(去中心化难管控) |
| 典型应用 | Web、Email、Netflix | BitTorrent、早期Skype |
为什么现在大多数应用还是客户端-服务器?
P2P 面临的挑战太多:安全问题(谁都能传文件,无法审核)、性能不稳定(节点时不时下线)、可靠性差,所以商业应用基本都用客户端-服务器。
2.1.2 进程通信(Processes Communicating)
程序 vs 进程
- 程序(Program):硬盘上的可执行文件
- 进程(Process):正在运行中的程序(有自己的内存空间、CPU时间)
比如你打开了两个浏览器窗口,是同一个程序启动了两个进程。
我们关心的是:运行在不同主机上的进程之间如何通信?
进程通信通过互联网**交换报文(messages)**来实现。
客户端进程 vs 服务器进程
定义:
- 客户端进程:主动发起通信的那一方
- 服务器进程:等待被联系的那一方
注意:这个定义是基于一次通信会话的,和"客户端-服务器架构"不完全一样。在 P2P 中,同一个节点在下载时是客户端进程,在上传时是服务器进程。
Web 访问示例:
浏览器(客户端进程) ──发起连接──> Web服务器(服务器进程)
主动联系 被动等待
套接字(Socket)——进程与网络的接口
类比:套接字就是进程的"门"
想象你的进程是一栋房子:
房子内部(进程)
|
[前门/套接字] <-- 消息从这里进出
|
门外的快递系统(传输层/网络)
|
对方的前门(对方的套接字)
|
对方的房子(对方进程)
套接字的正式定义:
套接字是应用层和传输层之间的接口,也被称为应用编程接口(API,Application Programming Interface)。
图 2.3 对应关系:
主机A 主机B
+---------------------------+ +---------------------------+
| 进程(应用开发者控制) | | 进程(应用开发者控制) |
| ^ | | ^ |
| | | | | |
| [Socket] | | [Socket] |
| ======应用层/传输层边界====| | ======应用层/传输层边界====|
| TCP缓冲区、变量(OS控制) |<---->| TCP缓冲区、变量(OS控制) |
+---------------------------+ 互联网 +---------------------------+
开发者能控制什么?
- 套接字上面(应用层):完全由开发者控制
- 套接字下面(传输层):由操作系统控制,开发者只能:
- 选择传输协议(TCP 或 UDP)
- 设置少数几个参数(如最大缓冲区大小、最大报文段大小)
知识点总览
应用架构对比总结
客户端-服务器(图 2.2a):
所有流量都指向中心服务器
[客户] --> [服务器]
[客户] --> [服务器]
[客户] --> [服务器]
[客户] --> [服务器]
P2P(图 2.2b):
节点之间直接互传
[节点A] <--> [节点B]
^ ^
| |
v v
[节点C] <--> [节点D]
关键术语速查
| 术语 | 解释 |
|---|---|
| 客户端(Client) | 发起通信请求的进程或主机 |
| 服务器(Server) | 等待并响应请求的进程或主机 |
| P2P | 对等架构,节点既是客户端也是服务器 |
| 自扩展性 | 用户越多,系统供给能力也越强 |
| 进程(Process) | 正在运行的程序实例 |
| 套接字(Socket) | 进程与网络之间的软件接口,即应用层的"门" |
| API | 应用编程接口,套接字是网络编程的 API |
| 数据中心 | 大量服务器的集合,对外充当"超级服务器" |
第二章:应用层(2.1 节)详细笔记
教材:Computer Networking: A Top-Down Approach(自顶向下方法)
2.1.2 进程寻址(Addressing Processes)
核心问题:如何找到目标进程?
寄信时需要收件人地址;同理,网络中一个进程想把数据发给另一台主机上的进程,也需要"地址"。
要定位一个接收进程,需要两个信息:
+----------------------------+
| 1. 主机地址(IP 地址) |
| 2. 端口号(Port Number) |
+----------------------------+
IP 地址
- IP 地址是一个 32 位的数值,可以唯一标识网络中的一台主机。
- 详细内容见第 4 章。
端口号(Port Number)
- 一台主机上可能同时运行很多网络应用(如浏览器、邮件客户端等)。
- 端口号用来区分同一台主机上的不同进程/应用。
- 常见的"知名端口号"(Well-Known Ports):
| 应用 | 协议 | 端口号 |
|---|---|---|
| Web 服务器 | HTTP | 80 |
| 邮件服务器 | SMTP | 25 |
完整的知名端口号列表可以在 www.iana.org 查到。
通信示意
发送方进程
|
| 目标:IP地址 + 端口号
v
[网络传输]
|
v
接收方主机(IP地址)
|
v
接收方进程(端口号)
2.1.3 传输层可以提供的服务
套接字(Socket) 是应用进程与传输层协议之间的接口。应用把消息"塞"进 socket,传输层负责把消息送到对端的 socket。
网络可以提供多种传输层协议,开发者需要根据应用需求选择合适的协议。
可以从以下 四个维度 来衡量传输层服务:
传输层服务
├── 1. 可靠数据传输(Reliable Data Transfer)
├── 2. 吞吐量(Throughput)
├── 3. 时延(Timing)
└── 4. 安全性(Security)
维度 1:可靠数据传输
问题背景:
- 数据包在网络中可能丢失(路由器缓冲区溢出、比特翻转等)。
两类应用对丢包的态度不同:
| 类型 | 特点 | 举例 |
|---|---|---|
| 不容忍丢失 | 必须保证数据完整到达 | 电子邮件、文件传输、网页、金融交易 |
| 容忍丢失(loss-tolerant) | 少量丢失可接受 | 音视频通话、在线游戏 |
举例:视频通话丢了几个包,画面可能有一点小卡顿,但不影响整体使用;而银行转账如果丢了数据,后果就很严重了。
维度 2:吞吐量(Throughput)
吞吐量:发送方向接收方传送比特的速率(单位:bps)。
- 由于网络中有很多会话共享带宽,可用吞吐量会随时间波动。
两类应用:
| 类型 | 说明 | 举例 |
|---|---|---|
| 带宽敏感型(Bandwidth-sensitive) | 需要最低吞吐量保证,否则无法正常工作 | 网络电话(需要 r r r bps 才能正常通话) |
| 弹性应用(Elastic) | 能充分利用当前可用带宽,多多益善 | 电子邮件、文件传输、网页 |
关键公式概念:
若一个应用需要保证吞吐量为 r r r bps,传输协议就需要确保可用吞吐量始终满足:
available_throughput ≥ r bps \text{available\_throughput} \geq r \text{ bps} available_throughput≥r bps
举例:网络电话编码速率为 32 kbps,则需要:
available_throughput ≥ 32 kbps \text{available\_throughput} \geq 32 \text{ kbps} available_throughput≥32 kbps
如果只有一半吞吐量,通话质量就会严重下降甚至无法使用。
维度 3:时延(Timing)
传输层可以提供时延保证,例如:
发送方塞入 socket 的每一个比特,到达接收方 socket 的时间不超过 100 ms。
时延敏感的实时应用:
- 网络电话:延迟过大会产生不自然的停顿
- 视频会议
- 多人在线游戏(元宇宙):延迟会导致操作和画面不同步,体验很差
非实时应用: - 延迟低当然更好,但没有严格的上限要求。
维度 4:安全性(Security)
传输层可以提供的安全服务:
发送方主机 接收方主机
| |
| 明文数据 |
v v
[传输层加密] -----> 密文在网络传输 ----> [传输层解密]
| |
v v
接收方进程获得明文数据
安全服务包括:
- 机密性(Confidentiality):数据加密,防止窃听
- 数据完整性(Data Integrity):防止数据被篡改
- 端点认证(End-point Authentication):确认通信对方身份
2.1.4 互联网提供的传输服务
互联网(TCP/IP 网络)提供两种传输协议:
互联网传输协议
├── TCP(Transmission Control Protocol)
└── UDP(User Datagram Protocol)
TCP 服务
TCP 提供两大核心服务:
(1) 面向连接的服务(Connection-Oriented Service)
客户端 服务器
| |
|------- 握手(Handshake)----->|
|<------ 握手响应 -------------|
| |
| TCP 连接建立(全双工) |
|<====== 双向数据传输 =========>|
| |
|------- 断开连接 ------------>|
- 通信前先"握手",双方做好准备
- 全双工(Full-duplex):双方可以同时互发数据
- 通信结束后需要"拆除连接"
(2) 可靠数据传输(Reliable Data Transfer)
- 保证数据无错误、按顺序到达
- 发送方把字节流塞入 socket,TCP 保证接收方收到完全一样的字节流,无丢失、无重复
(3) 拥塞控制(Congestion Control)
- 当网络拥堵时,TCP 会主动降低发送速率
- 这是为了整个网络的健康,而不只是某一对通信进程
- 让每个 TCP 连接公平地分享网络带宽
UDP 服务
UDP 是一个"轻量级、无附加功能"的协议:
| 特性 | 描述 |
|---|---|
| 无连接 | 不需要握手,直接发送 |
| 不可靠传输 | 不保证数据到达 |
| 无序 | 数据包可能乱序到达 |
| 无拥塞控制 | 可以以任意速率发送数据 |
UDP 就像"寄信不挂号"——发出去就不管了,速度快但不保证送达。
TCP 安全增强:TLS
TCP 和 UDP 本身都不提供加密,数据以明文在网络中传输。
为此,互联网社区开发了 TLS(Transport Layer Security,传输层安全):
应用进程
| 明文
v
[TLS Socket] <-- TLS 实现在应用层
| 加密后的数据
v
[TCP Socket]
|
v
网络传输(密文)
|
v
[TCP Socket]
| 密文
v
[TLS] 解密
| 明文
v
接收方应用进程
重要区分:
- TLS 不是第三种传输协议
- TLS 是在应用层实现的 TCP 增强
- 应用需要在客户端和服务端都引入 TLS 库
TLS 提供: - 加密(Encryption)
- 数据完整性(Data Integrity)
- 端点认证(End-point Authentication)
互联网传输协议不提供的服务
今天的 TCP 和 UDP 都不提供:
- 吞吐量保证
- 时延保证
但时延敏感的应用(如视频会议)仍然可以在互联网上运行,因为应用设计时已经考虑了这些不足。
当延迟过大或吞吐量严重不足时,再巧妙的设计也无济于事。
图表 2.4:应用需求对比(Image 1 内容)
| 应用 | 数据丢失 | 吞吐量 | 时延敏感 |
|---|---|---|---|
| 文件传输/下载 | 不允许丢失 | 弹性 | 否 |
| 电子邮件 | 不允许丢失 | 弹性 | 否 |
| 网页文档 | 不允许丢失 | 弹性(几 kbps) | 否 |
| 网络电话/视频会议 | 容忍丢失 | 音频:几 kbps–1 Mbps;视频:10 kbps–5 Mbps | 是(100s ms) |
| 流媒体音视频 | 容忍丢失 | 同上 | 是(几秒) |
| 互动游戏 | 容忍丢失 | 几 kbps–10 kbps | 是(100s ms) |
| 智能手机消息 | 不允许丢失 | 弹性 | 视情况 |
图表 2.5:常见应用与协议(Image 2 内容)
| 应用 | 应用层协议 | 传输层协议 |
|---|---|---|
| 电子邮件 | SMTP [RFC 5321] | TCP |
| 网页 | HTTP/2 [RFC 7540] | TCP |
| 文件传输 | FTP [RFC 959] | TCP |
| 流媒体 | HTTP(如 YouTube)、DASH | TCP |
| 网络电话 | SIP、RTP,或私有协议(如 Zoom) | UDP 或 TCP |
视频会议(如 Zoom)通常优先使用 UDP(避免拥塞控制的额外开销),但当防火墙屏蔽 UDP 时,会回退到 TCP。
2.1.5 应用层协议(Application-Layer Protocols)
进程通过 socket 互发消息,应用层协议规定了这些消息的"规则":
应用层协议定义了:
应用层协议规定
├── 消息类型(请求消息、响应消息等)
├── 消息语法(各字段的格式与划分方式)
├── 字段语义(每个字段的含义)
└── 规则(何时发送消息、如何响应)
两类协议:
| 类型 | 说明 | 举例 |
|---|---|---|
| 公开协议(RFC 标准) | 任何人可以实现,互通互联 | HTTP(网页)、SMTP(邮件) |
| 私有协议(Proprietary) | 不对外公开 | Zoom 使用的协议 |
重要区分:应用 vs 应用层协议
以 Web 为例:
Web 应用(整体)
├── HTML(文档格式标准)
├── 浏览器(Chrome、Edge 等)
├── Web 服务器(Apache、Nginx 等)
└── HTTP(应用层协议,只是 Web 的一部分)
以 Netflix 为例:
Netflix 应用(整体)
├── 视频存储和传输服务器
├── 计费和账户管理服务器
├── 客户端(手机 App、网页、TV)
└── DASH 协议(应用层协议,只是 Netflix 的一部分)
应用层协议是网络应用的重要组成部分,但不是全部。
2.1.6 本书涵盖的网络应用
本书重点讲解以下四类重要应用:
总结:TCP vs UDP 对比
TCP UDP
+---------------------------+ +---------------------------+
| 面向连接(需要握手) | | 无连接(直接发送) |
| 可靠传输(保证到达、有序) | | 不可靠传输(可能丢失/乱序) |
| 有拥塞控制(会限速) | | 无拥塞控制(发多快就多快) |
| 无吞吐量/时延保证 | | 无吞吐量/时延保证 |
| 可配合 TLS 提供安全性 | | 无内置安全机制 |
+---------------------------+ +---------------------------+
适用:邮件、网页、文件传输 适用:视频会议、在线游戏、
DNS 查询
知识结构导图
第二章 2.2 Web 与 HTTP 详解
2.2.1 HTTP 概述
Web 的核心概念
Web 页面(网页) 由多个**对象(object)**组成。一个对象就是一个文件,可以是:
- HTML 文件
- JPEG 图片
- JavaScript 文件
- CSS 样式表
- 视频片段
每个对象都有唯一的 URL(统一资源定位符) 来寻址。
URL 的结构:
http://www.someSchool.edu/someDepartment/picture.gif
|_________________| |__________________________|
主机名 路径名
(hostname) (pathname)
典型网页组成示例:
一个网页(假设有5张图片):
base HTML 文件(1个)
+ JPEG 图片(5个)
= 共 6 个对象,需要发起 6 次 HTTP 请求
HTTP 的工作方式(图 2.6)
HTTP(超文本传输协议)定义了客户端和服务器如何交换报文。
PC(Edge浏览器) ----HTTP请求----> Apache Web服务器
<---HTTP响应----
Android(Chrome) ----HTTP请求----> 同一台服务器
<---HTTP响应----
HTTP 基于 TCP:
- 客户端先建立 TCP 连接(默认端口 80)
- 连接建立后,双方通过套接字接口收发 HTTP 报文
- TCP 保证可靠传输,HTTP 不需要关心数据丢失问题——这正是分层架构的优势
HTTP 是无状态协议(Stateless Protocol):
服务器不保存任何关于客户端的状态信息。如果你在 5 秒内请求同一个对象两次,服务器会发送两次,它完全不记得刚才已经发过了。
类比:就像一个有失忆症的店员,每次你来都当作第一次见面。
HTTP 版本演变
| 版本 | 底层协议 | 特点 |
|---|---|---|
| HTTP/1.0 | TCP | 非持久连接 |
| HTTP/1.1 | TCP | 持久连接、流水线 |
| HTTP/2 | TCP | 多路复用、头部压缩 |
| HTTP/3 | UDP (QUIC) | 更低延迟 |
2.2.2 非持久连接与持久连接
非持久连接(Non-Persistent Connection)
规则:每个 TCP 连接只传送一个请求/响应对,传完就关闭。
完整流程示例(1个HTML + 10张JPEG):
获取一个对象所需时间(图 2.7):
客户端时间轴 服务器时间轴
| |
|---TCP SYN-----------------> |
| |
|<--TCP SYN-ACK-------------- | } 1个RTT(TCP握手前两步)
| |
|---TCP ACK + HTTP GET-------> | (第三次握手 + HTTP请求合并发送)
| |
| | 服务器发送文件(传输时延)
|<--HTTP响应(HTML文件)------- | } 1个RTT + 文件传输时间
| |
获取一个对象的总时间:
T 非持久 = 2 × RTT + T 传输 T_{\text{非持久}} = 2 \times \text{RTT} + T_{\text{传输}} T非持久=2×RTT+T传输
其中:
- 第一个 RTT:TCP 三次握手的前两步
- 第二个 RTT:HTTP 请求发出到响应回来
- T 传输 T_{\text{传输}} T传输:服务器传输该对象所需时间
获取整个网页(1 HTML + 10 JPEG)的总时间:
T total = 11 × ( 2 × RTT + T 传输 ) T_{\text{total}} = 11 \times (2 \times \text{RTT} + T_{\text{传输}}) Ttotal=11×(2×RTT+T传输)
(假设串行,每次都重新建立连接)
非持久连接的缺点:
- 每个对象都要新建 TCP 连接,开销大(需要分配缓冲区和变量)
- 每个对象多花一个 RTT 建立连接
- 服务器同时处理大量短连接,负担重
持久连接(Persistent Connection)
规则:TCP 连接在发送响应后保持打开,后续请求复用同一连接。
HTTP/1.1 和 HTTP/2 默认使用持久连接。
流水线(Pipelining): 不必等上一个响应回来就可以发下一个请求——就像工厂的流水线,多个请求同时在路上。
非持久连接(串行):
时间 → → → → → → → → → → → → → → → →
[建连][HTML][关][建连][img1][关][建连][img2][关]...
持久连接(有流水线):
时间 → → → → → → → → →
[建连][HTML+img1+img2+...+img10(一次连接全部传完)]
持久连接的优点:
- 减少 TCP 连接建立次数
- 减少因建立连接产生的 RTT 延迟
- 服务器压力小
2.2.3 HTTP 报文格式
HTTP 报文分两种:请求报文和响应报文,都是纯 ASCII 文本(人类可读)。
HTTP 请求报文
报文结构(图 2.8):
+------------------------------------------+
| 请求行(Request line) |
| 方法 空格 URL 空格 版本 回车 换行 |
+------------------------------------------+
| 首部行(Header lines) |
| 首部字段名: 空格 值 回车 换行 |
| 首部字段名: 空格 值 回车 换行 |
| ...(可有多行) |
+------------------------------------------+
| 空行(Blank line) |
| 回车 换行 |
+------------------------------------------+
| 实体体(Entity body) |
| (GET 时为空;POST 时包含表单数据) |
+------------------------------------------+
一个具体的请求报文示例:
GET /somedir/page.html HTTP/1.1\r\n
Host: www.someschool.edu\r\n
Connection: close\r\n
User-agent: Mozilla/5.0\r\n
Accept-language: fr\r\n
\r\n
(实体体为空,因为是GET请求)
逐行解析:
| 行 | 内容 | 含义 |
|---|---|---|
| 请求行 | GET /somedir/page.html HTTP/1.1 |
用GET方法请求这个路径,使用HTTP/1.1 |
| Host | www.someschool.edu |
目标服务器主机名(代理缓存需要用到) |
| Connection | close |
告诉服务器用完就关闭连接(不用持久连接) |
| User-agent | Mozilla/5.0 |
浏览器类型(服务器可据此返回不同版本) |
| Accept-language | fr |
希望收到法语版本(内容协商) |
HTTP 请求方法
| 方法 | 含义 | 实体体 | 典型用途 |
|---|---|---|---|
| GET | 请求一个对象 | 空 | 浏览网页(最常用) |
| POST | 提交数据 | 表单内容 | 登录、搜索、评论 |
| HEAD | 只要头部,不要正文 | 空 | 调试、检查对象是否存在 |
| PUT | 上传对象到指定路径 | 上传的文件 | Web 发布工具 |
| DELETE | 删除服务器上的对象 | 空 | 删除资源 |
GET vs POST 的区别:
GET 方式提交搜索(数据放在 URL 里):
www.google.com/search?q=monkeys&lang=en
(URL 会很长,数据暴露在地址栏,有长度限制)
POST 方式提交(数据放在实体体里):
URL: www.somesite.com/login
实体体: username=alice&password=123456
(数据不在 URL 中,更安全,无长度限制)
HTTP 响应报文
报文结构(图 2.9):
+------------------------------------------+
| 状态行(Status line) |
| 版本 空格 状态码 空格 短语 回车 换行 |
+------------------------------------------+
| 首部行(Header lines) |
| 首部字段名: 空格 值 回车 换行 |
| ... |
+------------------------------------------+
| 空行 |
+------------------------------------------+
| 实体体(Entity body) |
| (实际请求的对象内容) |
+------------------------------------------+
一个具体的响应报文示例:
HTTP/1.1 200 OK\r\n
Connection: close\r\n
Date: Mon, 21 Oct 2024 18:58:21 GMT\r\n
Server: Apache/2.2.3 (CentOS)\r\n
Last-Modified: Sun, 20 Oct 2024 13:20:46 GMT\r\n
Content-Length: 6821\r\n
Content-Type: text/html\r\n
\r\n
(HTML 文件内容...)
首部行逐行解析:
| 首部字段 | 示例值 | 含义 |
|---|---|---|
| Connection | close |
发完这个响应就关闭连接 |
| Date | Mon, 21 Oct 2024 18:58:21 GMT |
服务器发送响应的时间(不是文件创建时间) |
| Server | Apache/2.2.3 |
服务器软件类型(类似请求中的 User-agent) |
| Last-Modified | Sun, 20 Oct 2024 13:20:46 GMT |
对象最后修改的时间(缓存判断是否过期用) |
| Content-Length | 6821 |
实体体的字节数 |
| Content-Type | text/html |
对象类型(以此为准,不看文件扩展名) |
常见 HTTP 状态码
状态码记忆技巧:
2xx→ 成功(2=OK)3xx→ 去别处(3=转移)4xx→ 你的错(4=客户端)5xx→ 我的错(5=服务器)
非持久 vs 持久连接时延对比
非持久连接获取N个对象的总时间
T 非持久,串行 = N × ( 2 × RTT + T 传输 ) T_{\text{非持久,串行}} = N \times (2 \times \text{RTT} + T_{\text{传输}}) T非持久,串行=N×(2×RTT+T传输)
但可以并行建立多个 TCP 连接(浏览器通常并行开6~8个连接):
T 非持久,并行 ≈ 2 × RTT + T 传输,HTML + max ( T 传输,各对象 ) T_{\text{非持久,并行}} \approx 2 \times \text{RTT} + T_{\text{传输,HTML}} + \max(T_{\text{传输,各对象}}) T非持久,并行≈2×RTT+T传输,HTML+max(T传输,各对象)
持久连接(有流水线)获取N个对象
T 持久+流水线 ≈ RTT 建连 + RTT HTML + RTT 所有对象 + ∑ T 传输 T_{\text{持久+流水线}} \approx \text{RTT}_{\text{建连}} + \text{RTT}_{\text{HTML}} + \text{RTT}_{\text{所有对象}} + \sum T_{\text{传输}} T持久+流水线≈RTT建连+RTTHTML+RTT所有对象+∑T传输
对象足够多时,持久连接节省了 ( N − 1 ) (N-1) (N−1) 次建立连接的 RTT。
实战:用 curl 查看真实 HTTP 报文
在命令行输入:
curl -v http://gaia.cs.umass.edu/kurose_ross/index.php
-v(verbose,详细模式)会同时显示发出的请求报文和收到的响应报文。
输出示例:
> GET /kurose_ross/index.php HTTP/1.1 ← 请求行
> Host: gaia.cs.umass.edu ← 请求首部
> User-Agent: curl/7.68.0
>
< HTTP/1.1 200 OK ← 状态行
< Date: ... ← 响应首部
< Content-Type: text/html
< Content-Length: ...
<
<!DOCTYPE html>... ← 实体体(HTML内容)
本节知识总览
关键术语速查
| 术语 | 解释 |
|---|---|
| URL | 统一资源定位符,由主机名+路径名组成 |
| HTTP | 超文本传输协议,Web 的核心协议 |
| 无状态协议 | 服务器不保存客户端历史信息 |
| RTT | 往返时延,小包从客户端到服务器再回来的时间 |
| 非持久连接 | 每个对象用一个独立的 TCP 连接 |
| 持久连接 | 多个对象复用同一个 TCP 连接 |
| 流水线 | 不等响应就发送下一个请求 |
| 请求行 | HTTP 请求报文第一行:方法+URL+版本 |
| 状态行 | HTTP 响应报文第一行:版本+状态码+短语 |
| 实体体 | 报文的数据部分(GET请求中为空) |
2.2.4~2.2.7 Cookie、缓存、HTTP/2、HTTP/3
2.2.4 Cookie:用户与服务器的状态维护
为什么需要 Cookie?
HTTP 是无状态协议——服务器不记得你是谁。但现实中我们需要:
- 购物车(记住你放了什么商品)
- 登录状态(不用每次都输密码)
- 个性化推荐(根据你的浏览历史)
Cookie 就是在无状态的 HTTP 之上,构建出一个"有状态"的用户会话层。
Cookie 的四个组成部分
1. HTTP 响应报文中的 Set-cookie 首部行 (服务器 → 浏览器)
2. HTTP 请求报文中的 cookie 首部行 (浏览器 → 服务器)
3. 浏览器本地的 cookie 文件 (存在用户电脑上)
4. 服务器后端数据库 (存在服务器上)
Cookie 工作流程详解(图 2.10)
以 Susan 第一次访问 Amazon 为例:
Susan的浏览器 Amazon服务器 后端数据库
| | |
|-- 普通HTTP请求 ------------------> | |
| | 创建ID=1678 ------> |
| | 在DB中建立条目 |
| <-- HTTP响应 + Set-cookie:1678 --- | |
| | |
| 浏览器把 amazon:1678 写入cookie文件 | |
|(此前已有 ebay:8734) | |
| | |
|-- HTTP请求 + Cookie:1678 -------> | |
| | 查询DB(1678) -----> |
| | 执行个性化操作 |
| <-- 个性化HTTP响应 --------------- | |
| | |
| (一周后) | |
|-- HTTP请求 + Cookie:1678 -------> | |
| | 再次查询DB(1678) -> |
| <-- 推荐商品响应 ----------------- | |
Susan 浏览器本地的 cookie 文件:
# 网站 Cookie ID
ebay.com 8734 ← 之前访问eBay时设置的
amazon.com 1678 ← 刚才Amazon设置的
关键点: Amazon 不一定知道 Susan 的真实姓名,但它知道"编号 1678 的用户"访问了哪些页面、什么时候访问的。一旦 Susan 注册填写了个人信息,这些信息就和 1678 关联起来——这就是"一键购物"的底层原理。
Cookie 的争议:隐私问题
Cookie 使购物体验更便捷,但也带来隐私风险:
- 网站可以追踪你的浏览行为
- 这些数据可能被卖给第三方(广告商)
- 跨站追踪 Cookie 可以知道你在不同网站的行为
2.2.5 浏览器缓存(Browser Caching)
为什么要缓存?
获取一个对象最少需要 2 RTT 2\text{RTT} 2RTT(建立TCP连接 + HTTP请求/响应)。缓存的目标是:如果对象没有变化,就不需要重新从服务器下载,延迟可降为零!
浏览器缓存的工作原理:
用户请求对象
|
v
浏览器检查本地缓存
|
+--[有缓存且未过期]--> 直接从缓存返回,延迟=0,不访问网络
|
+--[有缓存但不确定是否过期]--> 发送条件GET,询问服务器
|
+--[无缓存]--> 正常发HTTP请求,得到响应后存入缓存
缓存控制机制一:Cache-Control
服务器在响应报文中告诉浏览器:这个对象可以缓存多久。
HTTP/1.1 200 OK
Cache-Control: max-age=3600 ← 可以缓存3600秒(1小时)
Content-Type: image/jpeg
...
常用指令:
| 指令 | 含义 |
|---|---|
Cache-Control: no-store |
不要缓存,每次都重新请求 |
Cache-Control: max-age=3600 |
可以缓存,有效期3600秒 |
Cache-Control: no-cache |
可以缓存,但每次都要向服务器验证 |
缓存控制机制二:条件GET(Conditional GET)
浏览器有缓存但不确定是否过期时,不直接下载整个对象,而是先问一下服务器:这个东西改过吗?
条件GET 请求(浏览器发出):
GET /fruit/kiwi.jpg HTTP/1.1
Host: www.exotiquecuisine.com
If-Modified-Since: Fri, 13 Sep 2024 09:23:24
含义:我缓存的版本是 2024年9月13日的,如果之后没改过,就别发给我了。
服务器的两种可能响应:
情况一:对象没有修改(节省带宽!)
HTTP/1.1 304 Not Modified
Date: Fri, 8 Nov 2024 12:07:29
Server: Apache/2.4.62
(实体体为空)
浏览器收到 304,知道缓存中的版本仍然有效,直接用缓存显示,不需要重新下载对象。
情况二:对象已经修改
HTTP/1.1 200 OK
Last-Modified: Mon, 4 Nov 2024 08:00:00
Content-Length: 10000
Content-Type: image/jpeg
(新的图片数据...)
浏览器收到 200,用新数据更新缓存。
条件GET的流程图:
2.2.6 HTTP/2
HTTP/1.1 的问题:队头阻塞(HOL Blocking)
设想一个网页:顶部有一个大视频,下面有 8 个小图标。
HTTP/1.1 用持久连接,但在一条 TCP 连接上是串行的:
TCP连接上的传输顺序(HTTP/1.1,无流水线):
[视频帧1][视频帧2]...[视频帧1000][图标1][图标2]...[图标8]
← 视频太大,后面的小图标全被堵住了 →
这就是队头阻塞:大对象排在队头,后面的小对象全部等待。
HTTP/1.1 的"野路子"解决方案:
开多条并行 TCP 连接(浏览器通常开 6 条),这样小对象可以走另一条连接。但这违背了 TCP 拥塞控制的公平性——相当于"插队抢带宽"。
HTTP/2 的核心改进:帧(Frame)与多路复用
核心思想:把每个 HTTP 消息拆成小帧,多条消息的帧交错发送(多路复用)。
HTTP/2 在一条 TCP 连接上的传输顺序(帧交错):
[视频帧1][图标1_帧1][图标2_帧1]...[图标8_帧1]
[视频帧2][图标1_帧2][图标2_帧2]...[图标8_帧2]
[视频帧3]...
所有小图标只需等 18 帧就全部收到!
而不是等视频的 1000 帧发完才轮到它们(总共1016帧)。
效果对比:
| 方式 | 小对象何时收完 |
|---|---|
| HTTP/1.1(单连接串行) | 发完1016帧后 |
| HTTP/2(帧交错) | 发完18帧后 |
HTTP/2 还有两个附加特性:
1. 请求优先级(Priority)
客户端可以给每个请求分配权重(1~256),服务器优先发送高优先级的帧。
2. 服务器推送(Server Push)
服务器解析 HTML 后,主动把页面需要的对象推送给客户端,不用等客户端一个一个来请求。
传统方式:
客户端请求HTML → 服务器返回HTML
客户端解析HTML发现需要kiwi.jpg → 请求kiwi.jpg → 服务器返回
服务器推送:
客户端请求HTML → 服务器返回HTML + 主动推送kiwi.jpg
(节省了客户端解析HTML再发请求的时间)
2.2.7 HTTP/3 与 QUIC
HTTP/2 还有什么问题?
HTTP/2 把 HOL 阻塞问题从"应用层"解决了,但传输层(TCP)还有问题:
HTTP/2 的多个流都跑在同一条 TCP 连接上:
流1(视频) : [帧A][帧B][ X ][帧D] ← X 表示丢包
流2(图标1): [帧a][帧b][帧c][帧d]
流3(图标2): [帧α][帧β][帧γ][帧δ]
TCP 发现 X 丢失,要求重传 X。
在 X 重传之前,TCP 不允许交付后面的任何数据。
→ 流2 和流3 的数据即使已经收到,也被阻塞,无法递交给应用!
这就是 TCP 层面的队头阻塞,HTTP/2 解决不了,因为它在 TCP 之上。
QUIC 协议
QUIC = Quick UDP Internet Connections(基于UDP的快速互联网连接)
QUIC 的层次位置(图 2.11):
传统 HTTPS(HTTP/2): HTTP/3:
+------------------+ +----------------------+
| HTTP/2 | | HTTP/2(精简版) |
+------------------+ +------ HTTP/3 --------+
| TLS(加密层) | | QUIC(含TLS 1.3) |
+------------------+ +----------------------+
| TCP(传输层) | | UDP(传输层) |
+------------------+ +----------------------+
| IP(网络层) | | IP(网络层) |
+------------------+ +----------------------+
QUIC 严格来说是应用层的一个子层(因为它跑在UDP上面),但从开发者角度看,它就像一个新的传输层协议——可以像 TCP/UDP 一样创建 QUIC socket。
QUIC 解决了哪些问题?
问题一:双握手延迟(传统 HTTPS 需要 TCP 握手 + TLS 握手)
传统 HTTPS(HTTP/2)的连接建立:
客户端 服务器
|--- TCP SYN ------------------> |
|<-- TCP SYN-ACK --------------- | } TCP握手:1 RTT
|--- TCP ACK ------------------> |
|--- TLS ClientHello ----------> |
|<-- TLS ServerHello + 证书 ---- | } TLS握手:1~2 RTT
|--- TLS Finished --------------> |
| |
|--- HTTP 请求 -----------------> | 才开始传数据!
总计:2~3 RTT 才能开始传数据
QUIC(HTTP/3)的连接建立:
客户端 服务器
|--- QUIC Initial(含TLS)------> |
|<-- QUIC Response(含TLS)----- | } 连接+加密 合并:1 RTT
|--- HTTP 请求 -----------------> | 立刻传数据!
总计:1 RTT 即可开始传数据
若之前连接过(会话复用):0 RTT!
QUIC 把 TCP 握手和 TLS 握手合并成一次,这就是"Quick"的来源。
问题二:TCP 层面的队头阻塞
QUIC 用"流(Stream)"的概念管理多个 HTTP 消息:
QUIC 连接上的多个独立流:
流1(视频) : [帧A][帧B][ X ][帧D] ← X 丢包,只影响流1
流2(图标1): [帧a][帧b][帧c][帧d] ← 不受影响,正常递交
流3(图标2): [帧α][帧β][帧γ][帧δ] ← 不受影响,正常递交
流之间相互独立! 一条流的丢包不会阻塞其他流——彻底解决了队头阻塞问题。
HTTP 版本全面对比
| 特性 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|---|
| 底层协议 | TCP | TCP | TCP | UDP(QUIC) |
| 连接方式 | 非持久 | 持久 | 持久 | QUIC连接 |
| 多路复用 | 无 | 有限(流水线) | 有(帧交错) | 有(流) |
| HOL阻塞 | 严重 | 有 | 应用层解决 | 彻底解决 |
| 加密 | 无 | 可选TLS | 可选TLS | 内置TLS 1.3 |
| 连接建立 | 1RTT | 1RTT | 1RTT | 1RTT(或0RTT) |
| 头部压缩 | 无 | 无 | 有(HPACK) | 有(QPACK) |
HTTP 协议演进总结图
本节知识点速查
| 概念 | 核心要点 |
|---|---|
| Cookie | 4部分:响应头Set-cookie、请求头Cookie、浏览器cookie文件、服务器数据库 |
| Cookie作用 | 在无状态HTTP上构建有状态会话(购物车、登录、推荐) |
| 浏览器缓存 | 本地存储对象,命中时延迟=0 |
| Cache-Control | 服务器指定缓存有效期(max-age)或禁止缓存(no-store) |
| 条件GET | 带If-Modified-Since头,未修改返回304(空body),修改了返回200+新数据 |
| 304 Not Modified | 对象未修改,使用缓存,不传输对象体,节省带宽 |
| HOL阻塞 | 大对象排队头,小对象被堵住 |
| HTTP/2 帧 | 把HTTP消息拆成帧,多个消息的帧交错发送,解决应用层HOL |
| 服务器推送 | 服务器主动发送客户端需要但未请求的对象 |
| QUIC | 基于UDP,内置TLS,流之间独立,彻底解决HOL,1RTT建连 |
| HTTP/3 | 运行在QUIC上,不是TCP |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)