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)} 平均吞吐量=TFbits/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 分层架构

为什么要分层?

互联网是一个极其复杂的系统。分层架构的好处:

  1. 模块化:每层只关心自己的职责
  2. 易于维护:修改某层实现不影响其他层
  3. 便于讨论:可以针对某一层单独分析
航空公司类比

用坐飞机的流程来类比网络的分层:

出发机场                中间空管中心              到达机场
-----------           ---------------           -----------
购票(Ticket)                                    投诉(Ticket)
托运行李(Baggage)                               取行李(Baggage)
登机口(Gate/load)                               登机口(Gate/unload)
跑道起飞(Takeoff)                               跑道降落(Landing)
飞机路由(Routing) <--> 飞机路由(Routing) <--> 飞机路由(Routing)

关键思想:每层只服务于上层,并依赖下层提供的服务。就像你进登机口之前,必须已经完成了购票和托运。
对应到网络中:每个协议层通过以下两种方式提供服务:

  1. 在本层执行特定操作
  2. 使用下层提供的服务

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:封装与传输流程图

加Ht

加Hn

加Hl

应用层: Message M

传输层: Segment Ht+M

网络层: Datagram Hn+Ht+M

链路层: Frame Hl+Hn+Ht+M

物理层: 逐bit发送

链路层交换机
只看链路层头部Hl

路由器
处理到网络层Hn

目标主机
逐层解封装

应用层: 还原Message M

协议分层的优缺点总结

优点:

  • 结构清晰,便于理解和讨论复杂系统
  • 模块化设计,修改某层不影响其他层
  • 易于标准化和互操作
    缺点(也有反对者):
  • 某些功能可能在多层重复实现(如错误恢复在链路层和传输层都有)
  • 某层可能需要另一层的信息(如时间戳),违反了层间分离的原则

知识点速查


概念 说明
瞬时吞吐量 某时刻接收方的接收速率
平均吞吐量 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×rR
    即可使目标链路瘫痪。
DDoS 攻击示意图(对应图 1.26)
攻击者(Attacker)
    |
    |-- "start attack" --> zombie A --|
    |-- "start attack" --> zombie B --|--> 路由器 --> Victim(受害者)
    |-- "start attack" --> zombie C --|
    |-- "start attack" --> zombie D --|

用 Mermaid 表示:

发出攻击指令

发出攻击指令

发出攻击指令

发出攻击指令

洪泛流量

洪泛流量

洪泛流量

洪泛流量

攻击者 Attacker

zombie A

zombie B

zombie C

zombie D

路由器/目标接入点

Victim 受害者

每年约有 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)

1961 Kleinrock 提出分组交换理论

1969 ARPAnet 第一台分组交换机
UCLA 安装,4个节点

1972 ARPAnet 15节点
NCP协议完成
第一封电子邮件

1970s 多网络涌现
ALOHANet / Ethernet
TCP/IP 概念确立

1983 ARPAnet 切换到TCP/IP
旗帜日 Flag Day

1986 NSFNET 建立
DNS 诞生

1989-1991 Tim Berners-Lee
发明 World Wide Web

1993 Mosaic 浏览器
Netscape 成立

1995-2001 互联网泡沫
电商/即时通讯/P2P兴起

2000s 宽带普及
社交网络兴起
云计算出现

2011 无线设备数超有线
智能手机时代

至今 5G / LEO卫星
AI / 视频流媒体

知识点速查


概念 说明
恶意软件(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=NRL
推广: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} NRL,之后每隔 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+P1)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}} sdtrans 米:
距发送方 = s ⋅ d trans = s ⋅ L R  米 \text{距发送方} = s \cdot d_{\text{trans}} = s \cdot \frac{L}{R} \text{ 米} 距发送方=sdtrans=sRL 
因为 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 sRL<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=sRL=2.5×108×10712000=2.5×108×1.2×103=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.9120n
(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(X51)=n=51120(n120)×0.1n×0.9120n
这个值极小(远小于 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×1011,几乎为零。

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=13RiL+i=13sidi+2dproc
其中:

  • 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,,N1)到达时,前面有 k k k 个分组等待:
d queue ( k ) = k ⋅ L R d_{\text{queue}}(k) = k \cdot \frac{L}{R} dqueue(k)=kRL
平均排队时延:
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=0N1kRL=RL2N1
(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(N1)

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×(n1)=n2nn2( n 很大时)
Metcalfe 定律:网络价值 ∝ n 2 \propto n^2 n2,与上面的消息数 n ( n − 1 ) ≈ n 2 n(n-1) \approx n^2 n(n1)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) TRcLRsL=L(Rc1Rs1)

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 s46 
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宽度=Rs1=Rs(米/比特)
更直观地:链路总长 m m m 米,可以放 R ⋅ m / s = BDP R \cdot m / s = \text{BDP} Rm/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+1001)×2 ms=102×2=204 ms=0.204 s
与 P2 中的公式 ( N + P − 1 ) ⋅ L R (N + P - 1) \cdot \frac{L}{R} (N+P1)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/SF/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+P1)RL=(3+SF1)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(2S280F)=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 常见的分组大小量级相近。

知识体系总览

计算机网络

网络边缘

网络核心

性能指标

体系结构

端系统与应用

接入网技术

分组交换
统计复用 灵活高效

电路交换
资源预留 实时稳定

ISP层次结构

时延
传输+传播+排队+处理

吞吐量
min瓶颈链路

丢包

五层协议栈

封装与解封装

应用层 HTTP SMTP

传输层 TCP UDP

网络层 IP

链路层 Ethernet WiFi

物理层 信号传输

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 请求,完整流程如下:

Web服务器 128.119.245.12 浏览器 192.168.1.128 Web服务器 128.119.245.12 浏览器 192.168.1.128 第56号包就是这个GET请求 TCP连接建立(三次握手) HTTP GET /wireshark-labs/INTRO-wireshark-file1.html HTTP/1.1 200 OK(返回HTML内容) TCP ACK 确认收到

从第 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 技术的爆发式发展,认为这是下一代人的巨大机遇

给学生的建议

“互联网及其所带来的一切是一片广阔的新疆界,充满了令人惊叹的挑战。这里有巨大的创新空间。不要被今天的技术所束缚。勇于想象未来可能是什么样子,然后让它成为现实。”

三、本章知识体系总览

第一章:计算机网络
与互联网

网络组成

核心概念

实验工具

历史人文

端系统与应用

接入网与物理媒介

网络核心
分组交换 vs 电路交换

ISP层次结构

性能指标
时延 吞吐量 丢包

协议分层
五层协议栈

封装与解封装

Wireshark
分组嗅探器

捕获真实数据包

观察各层协议字段

贯穿全书各章实验

Leonard Kleinrock
分组交换理论创始人

1961年 分组交换数学理论

1969年 互联网第一个节点

第一条消息 Lo

四、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控制)   |
+---------------------------+  互联网  +---------------------------+

开发者能控制什么?

  • 套接字上面(应用层):完全由开发者控制
  • 套接字下面(传输层):由操作系统控制,开发者只能:
    1. 选择传输协议(TCP 或 UDP)
    2. 设置少数几个参数(如最大缓冲区大小、最大报文段大小)

知识点总览

第二章 应用层

2.1 网络应用原理

后续章节

应用架构

进程通信

客户端-服务器
永远在线的服务器
固定IP
数据中心

P2P
无专用服务器
自扩展性
去中心化

客户端进程
主动发起通信

服务器进程
等待被联系

套接字Socket
应用层与传输层的接口
进程的门

应用层侧
开发者完全控制

传输层侧
操作系统控制
开发者只选协议

HTTP Web

电子邮件 SMTP

DNS

视频流

Socket编程

应用架构对比总结

客户端-服务器(图 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_throughputr bps

举例:网络电话编码速率为 32 kbps,则需要:
available_throughput ≥ 32  kbps \text{available\_throughput} \geq 32 \text{ kbps} available_throughput32 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 本书涵盖的网络应用

本书重点讲解以下四类重要应用:

本书网络应用

Web

电子邮件 E-mail

目录服务 DNS

视频流 Video Streaming

使用 HTTP 协议
相对简单,易于理解

互联网第一个杀手级应用
使用多个应用层协议

域名到IP地址的转换
在应用层实现核心网络功能

点播视频流
通过 CDN 分发

总结:TCP vs UDP 对比

TCP                              UDP
+---------------------------+    +---------------------------+
| 面向连接(需要握手)        |    | 无连接(直接发送)          |
| 可靠传输(保证到达、有序)   |    | 不可靠传输(可能丢失/乱序) |
| 有拥塞控制(会限速)        |    | 无拥塞控制(发多快就多快)   |
| 无吞吐量/时延保证           |    | 无吞吐量/时延保证           |
| 可配合 TLS 提供安全性       |    | 无内置安全机制              |
+---------------------------+    +---------------------------+
适用:邮件、网页、文件传输         适用:视频会议、在线游戏、
                                        DNS 查询

知识结构导图

应用层 2.1 节

进程寻址

传输层服务

互联网传输协议

应用层协议

IP地址:标识主机

端口号:标识进程

可靠数据传输

吞吐量

时延

安全性

TCP

UDP

TLS增强TCP

面向连接

可靠传输

拥塞控制

无连接

不可靠传输

无拥塞控制

消息类型/语法/语义/规则

公开协议 vs 私有协议

第二章 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:

  1. 客户端先建立 TCP 连接(默认端口 80)
  2. 连接建立后,双方通过套接字接口收发 HTTP 报文
  3. 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):

服务器 客户端 服务器 客户端 第1次TCP连接(获取HTML) 连接关闭,客户端解析HTML发现10个JPEG 第2~11次TCP连接(各获取一张JPEG) 共建立11次TCP连接 TCP三次握手(SYN) TCP三次握手(SYN-ACK) HTTP GET /home.index(携带ACK) HTTP响应(返回HTML文件) 为每张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传输)
    (假设串行,每次都重新建立连接)
    非持久连接的缺点:
  1. 每个对象都要新建 TCP 连接,开销大(需要分配缓冲区和变量)
  2. 每个对象多花一个 RTT 建立连接
  3. 服务器同时处理大量短连接,负担重

持久连接(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 状态码

HTTP状态码

2xx 成功

3xx 重定向

4xx 客户端错误

5xx 服务器错误

200 OK
请求成功,返回对象

301 Moved Permanently
永久移动到新URL

400 Bad Request
请求格式有误

404 Not Found
对象不存在

505 HTTP Version Not Supported
不支持该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) (N1) 次建立连接的 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内容)

本节知识总览

2.2 Web与HTTP

基本概念

连接方式

报文格式

Web页面由对象组成
每个对象有唯一URL

HTTP基于TCP
默认端口80

HTTP是无状态协议
服务器不记忆客户端

非持久连接
每对象一个TCP连接
时延=2RTT+传输时间

持久连接
多对象复用一个TCP
HTTP1.1默认

流水线
不等响应就发下一请求

请求报文
请求行+首部行+空行+实体体

响应报文
状态行+首部行+空行+实体体

方法: GET POST HEAD PUT DELETE

状态码: 200 301 400 404 505

关键术语速查


术语 解释
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的流程图:

服务器 浏览器 服务器 浏览器 第一次请求 存入缓存,记录日期Sep 13 再次请求(不确定是否过期) 继续使用缓存 更新缓存 alt [图片未修改] [图片已修改] GET /kiwi.jpg HTTP/1.1 200 OK + 图片数据 Last-Modified: Sep 13 GET /kiwi.jpg If-Modified-Since: Sep 13 304 Not Modified (空实体体,节省带宽) 200 OK + 新图片数据

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 协议演进总结图

解决连接复用

解决HOL阻塞
帧交错多路复用

解决TCP层HOL
改用UDP+QUIC

HTTP/1.0
1996年
非持久连接

HTTP/1.1
1997年
持久连接+流水线

HTTP/2
2015年
帧+多路复用

HTTP/3
2022年
QUIC+0RTT

本节知识点速查


概念 核心要点
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

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐