COMP5416 Week 04 DNS 与 P2P 讲课总结
COMP5416 Week 04 讲课总结:DNS 与 P2P
课程:COMP5416/COMP4416 — Advanced Network Technologies,Semester 2 2026 讲师:Professor Vincent Gramoli 讲义:
W4-DSN-P2P.pdf(48 页) 教材:Kurose & Ross 9th ed. —— 第 2 章,2.4 / 2.5 / 2.6 节⚠️ Midterm quiz 在 Week 6,20 道选择题,占 20%。 ✅ 老师已说明:期中不考 Week 6 的内容,范围就是 Week 1–5。
本讲三大块:DNS → 套接字编程 → P2P(含 DHT)。 文件分发时间公式和 DHT 后继节点是最可能出计算题的地方。
第一部分:DNS
一、为什么需要 DNS
两套标识体系
互联网主机和路由器同时有两种标识:
| 标识 | 长度 | 用途 | 谁在用 |
|---|---|---|---|
| IP 地址 | 32 位(IPv4) | 用于给数据报寻址 | 机器 |
| 名字 | 可变 | 如 www.yahoo.com |
人 |
讲义的类比:人也有很多标识 —— 姓名、护照号。 姓名给人叫,护照号给系统查 —— 和「域名 vs IP」是同一回事。
DNS = Domain Name System,它同时是两样东西:
- 一个分布式数据库,实现在许多名字服务器的层级结构中
- 一个应用层协议 —— 主机与名字服务器通信以完成名字解析
二、为什么不用集中式 DNS(高频 MCQ)
| 理由 | 说明 |
|---|---|
| 单点故障 | single point of failure —— 那台服务器挂了整个互联网就瘫了 |
| 距离远 | 集中式数据库对远处的用户时延高 |
| 可扩展性 | scalability —— 一台机器扛不住全球查询量 |
💡 讲义只列了这三条,原书还有第四条「维护量大」(要为全球所有主机维护记录)。 考试记住讲义的三条一定够,但四条都写也不会错。
三、DNS 提供的服务(不止翻译名字)
| 服务 | 说明 |
|---|---|
| 主机名 → IP 地址翻译 | 最基本的 |
| 主机别名(host aliasing) | 规范名(canonical)与别名(alias) |
| 邮件服务器别名 | mail server aliasing |
| 负载分配(load distribution) | 复制的 Web 服务器:一个名字对应多个 IP 地址 |
「DNS 可以做负载均衡」是很容易被忽略的考点。 原理:一个域名的 A 记录里放一组 IP,DNS 服务器每次响应时轮换(rotate)返回顺序, 客户通常用第一个,于是流量就被分散到不同服务器上了。
四、DNS 的层级结构
Root DNS Servers |
解析
www.amazon.com 的一级近似(讲义 p5)
| 步骤 | 动作 |
|---|---|
| 1 | 客户查根服务器,找到 com DNS 服务器 |
| 2 | 客户查 .com DNS 服务器,找到 amazon.com DNS 服务器 |
| 3 | 客户查 amazon.com DNS
服务器,拿到 www.amazon.com 的 IP |
注意这是「一级近似」 —— 真实过程中间还有本地 DNS 服务器代劳,见第六节。
五、四类 DNS 服务器(必考)
| 类型 | 职责 | 关键细节 |
|---|---|---|
| Root(根) | 层级的顶点 | 全球 13 个根名字「服务器」(逻辑上 13 个,每个都有大量镜像站点) |
| TLD(顶级域) | 负责 com、org、net、edu、aero、jobs、museums 以及所有国家顶级域(uk、fr、ca、jp) | 💡 Network Solutions 维护 .com;Educause 维护 .edu |
| Authoritative(权威) | 组织自己的 DNS 服务器,提供该组织主机的权威名字→IP 映射 | 可由组织自己维护,也可外包给服务商 |
| Local(本地) | 见下节 | 严格来说不属于这个层级结构! |
根服务器的「13 个」是怎么回事
讲义 p6 列出了 a 到 m 共 13 个字母标识的根服务器,分布在 Verisign、USC-ISI、ICANN、NASA、 Internet Software Consortium、Netnod、RIPE、WIDE、Cogent、马里兰大学、ARL、美国国防部等机构。
每一个「服务器」实际上是很多台机器(如
l.有 41 个站点,j.有 69 个站点)—— 靠任播(anycast)让用户访问到最近的那台。 「13」这个数字来自早期 UDP 报文大小限制,考试问「有几个根服务器」答 13 即可。
六、本地 DNS 服务器(易考细节)
| 特性 | 说明 |
|---|---|
| 层级归属 | 不严格属于该层级结构 —— 这是最容易被考的一点 |
| 谁有 | 每个 ISP(住宅 ISP、公司、大学)都有一个 |
| 别名 | 也叫「默认名字服务器」(default name server) |
| 作用 | 主机发 DNS 查询时,查询先发给它 |
| 缓存 | 有最近「名字→地址」的本地缓存(⚠️ 但可能过时!) |
| 角色 | 充当代理(proxy),把查询转发进层级结构 |
为什么它「不属于层级」:根、TLD、权威三类是有明确从属关系的树形结构, 而本地 DNS 服务器只是你所在网络的一个代理,谁都能架一个(比如 8.8.8.8、1.1.1.1), 它不「拥有」任何域的权威数据。
七、迭代查询 vs 递归查询(必考对照)
场景(讲义 p9–p10):cis.poly.edu
上的主机想要 gaia.cs.umass.edu 的 IP。
迭代查询(Iterated)
机制:被联系的服务器回复「下一个该问谁」的服务器名字。 那句话:「我不知道这个名字,但你去问那台服务器。」
8 条消息的完整流程:
| # | 方向 | 内容 |
|---|---|---|
| 1 | 主机 → 本地 DNS | 查询 gaia.cs.umass.edu |
| 2 | 本地 DNS → 根 | 查询 |
| 3 | 根 → 本地 DNS | 「去问 .edu TLD」 |
| 4 | 本地 DNS → TLD (.edu) | 查询 |
| 5 | TLD → 本地 DNS | 「去问 dns.cs.umass.edu」 |
| 6 | 本地 DNS → 权威 | 查询 |
| 7 | 权威 → 本地 DNS | 返回 IP |
| 8 | 本地 DNS → 主机 | 返回 IP |
本地 DNS 服务器跑了 3 个来回(2-3、4-5、6-7),负担全在它身上。
递归查询(Recursive)
机制:把名字解析的负担交给被联系的名字服务器。 问题:层级上层负载重(heavy load at upper levels)。
8 条消息的完整流程:
| # | 方向 | 内容 |
|---|---|---|
| 1 | 主机 → 本地 DNS | 查询 |
| 2 | 本地 DNS → 根 | 查询 |
| 3 | 根 → TLD | 代为查询(查询沿层级下行) |
| 4 | TLD → 权威 | 代为查询 |
| 5 | 权威 → TLD | 返回 IP |
| 6 | TLD → 根 | 返回 IP(答案沿层级上行) |
| 7 | 根 → 本地 DNS | 返回 IP |
| 8 | 本地 DNS → 主机 | 返回 IP |
两者的对比
| 维度 | 迭代 | 递归 |
|---|---|---|
| 消息总数 | 8(本例) | 8(本例) |
| 谁承担往返 | 本地 DNS 反复跑 | 层级逐级转发 |
| 形状 | 星形(都以本地 DNS 为中心) | 链形(下行查询、上行应答) |
| 上层负载 | 低 | 高 —— 根服务器要参与整条链 |
区分口诀: 迭代 = 服务器给你「指路」,你自己去跑; 递归 = 服务器替你「跑腿」,直接把答案带回来。
实践中的混合用法:主机 → 本地 DNS 通常是递归(主机很懒,只想要答案), 本地 DNS → 层级结构通常是迭代(根服务器不愿意替全世界跑腿)。
八、DNS 缓存与记录更新
| 要点 | 说明 |
|---|---|
| 谁会缓存 | 任何名字服务器学到映射后都会缓存它 |
| 缓存多久 | 缓存条目在一段时间后超时消失 —— 这个时间叫 TTL |
| 副作用 | 缓存条目可能过时 ⇒ DNS 是「尽力而为」的名字→地址翻译 |
| ⚠️ 最麻烦的场景 | 如果主机改了 IP 地址,在所有 TTL 过期之前,全网可能都还不知道 |
| 更新机制 | RFC 2136(IETF 提案标准) |
实践含义:要迁移服务器时,运维会提前几天把 TTL 调小(比如从 86400 秒降到 300 秒), 这样切换当天全网能很快跟上。这是「TTL 决定了变更的传播速度」的直接应用。
九、DNS 资源记录(RR)—— 必考
RR 格式:(name, value, type, ttl)
| 类型 | name 是什么 | value 是什么 | 助记 |
|---|---|---|---|
| A | 主机名 | IP 地址 | Address |
| NS | 域名(如
foo.com) |
该域权威名字服务器的主机名 | Name Server |
| CNAME | 某个「规范(真实)名」的别名 | 规范名 | Canonical NAME |
| MX | 域名 | 与该名字关联的邮件服务器名字 | Mail eXchange |
CNAME 的实例(讲义 p12):www.ibm.com
实际上是 servereast.backup2.ibm.com。
四种类型必须能秒答。一句话记忆: A 给 IP;NS 给服务器名;CNAME 给真名;MX 给邮件服务器。
十、往 DNS 里插入记录(讲义 p13)
场景:新创业公司 "Network Utopia"
| 步骤 | 动作 |
|---|---|
| 1 | 在 DNS 注册商(如 Network
Solutions)注册 networkutopia.com |
| 2 | 提供权威名字服务器的名字和 IP |
| 3 | 注册商往 .com TLD 服务器插入两条 RR |
| 4 | 自己在权威服务器上创建记录 |
注册商插入 TLD 的两条:
(networkutopia.com, dns1.networkutopia.com, NS) |
自己在权威服务器上创建:
(www.networkutopia.com, 212.212.212.22, A) |
「NS + A 成对出现」是常考点: NS 记录只给出服务器的「名字」(
dns1.networkutopia.com), 还需要一条 A 记录给出它的「IP」(212.212.212.1),否则拿到名字也联系不上 —— 这就是所谓的「胶水记录(glue record)」。
第二部分:套接字编程
十一、套接字基础
套接字:应用进程与端到端传输协议之间的门。
控制权划分(讲义 p15 的图,考点):
┌─────────────────┐ |
| 部分 | 谁控制 |
|---|---|
| 应用层 | 应用开发者控制 |
| 传输层及以下 | 操作系统控制 |
考点:开发者唯一能选的传输层参数就是「用 TCP 还是 UDP」以及少数几个选项, 其余(拥塞窗口、重传定时器等)全在内核里,动不了。
两种套接字对应两种传输服务:
| 套接字类型 | 传输服务 |
|---|---|
SOCK_DGRAM |
UDP:不可靠数据报 |
SOCK_STREAM |
TCP:可靠、面向字节流 |
讲义的示例应用(贯穿 UDP/TCP 两版代码):
- 客户从键盘读一行字符,发给服务器
- 服务器收到后转成大写
- 服务器把改后的数据发回客户
- 客户收到并显示
十二、UDP 套接字编程
特点(讲义 p17)
| 特点 | 说明 |
|---|---|
| 无连接 | 客户与服务器之间没有「连接」,发数据前无握手 |
| 发送方的责任 | 给每个分组显式附上目的 IP 和端口号 |
| 接收方的动作 | 从收到的分组中提取发送方的 IP 和端口号 |
| 可靠性 | 传输的数据可能丢失或乱序到达 |
应用视角:UDP 在客户与服务器之间提供「字节组(数据报)」的不可靠传输。
交互流程(讲义 p18)
服务器(运行在 serverIP) 客户 |
Python 代码要点(讲义 p19–20)
客户端:
from socket import * |
服务器端:
serverSocket = socket(AF_INET, SOCK_DGRAM) |
三个要注意的细节:
- 客户端没有
bind()—— 操作系统自动分配一个临时端口recvfrom()返回两样东西:数据 和 发送方地址 —— 这是 UDP 独有的encode/decode是 Python 3 的新要求(讲义特意标注了 "New feature in Python 3")
十三、TCP 套接字编程
特点(讲义 p21)
| 要求 | 说明 |
|---|---|
| 服务器进程必须先运行 | 客户才能联系它 |
| 服务器必须先创建「欢迎套接字」 | 迎接客户的到来 |
| 客户主动发起 | 创建 TCP 套接字,指定服务器的 IP 和端口 |
| TCP 建立连接 | 客户 TCP 与服务器 TCP 建立连接 |
关键机制:服务器的「两个套接字」(极易考)
讲义原文:当被客户联系时,服务器 TCP 会「创建一个新的套接字」 供服务器进程与这个特定客户通信。
| 好处 | 说明 |
|---|---|
| 允许服务器同时与多个客户对话 | 每个客户一个专属套接字 |
| 区分不同客户靠什么 | 源端口号(source port numbers) |
两个套接字的角色:
| 套接字 | 何时创建 | 作用 | 何时关闭 |
|---|---|---|---|
serverSocket(欢迎套接字) |
启动时 | listen()
等待连接请求 |
不关闭(要一直接客) |
connectionSocket(连接套接字) |
accept()
返回时 |
与该特定客户通信 | 通信完关闭它 |
交互流程(讲义 p22)
服务器(运行在 hostid) 客户 |
Python 代码要点(讲义 p23–24)
客户端:
clientSocket = socket(AF_INET, SOCK_STREAM) # TCP 套接字 |
服务器端:
serverSocket = socket(AF_INET, SOCK_STREAM) |
十四、UDP vs TCP 套接字对照(考点汇总)
| 维度 | UDP | TCP |
|---|---|---|
| socket 类型 | SOCK_DGRAM |
SOCK_STREAM |
| 连接 | 无握手 | 必须先 connect() /
accept() |
| 地址附加在哪 | 每个分组都要附目的 IP + 端口 | 只在建连时指定一次 |
| 客户端调用 | sendto() /
recvfrom() |
connect() /
send() / recv() |
| 服务器端调用 | bind() /
recvfrom() / sendto() |
bind() /
listen() /
accept() / recv() /
send() |
| 接收方能否知道发送方 | 能(recvfrom()
返回地址) |
建连时就知道了 |
| 服务器套接字数量 | 1 个 | 1 个欢迎 + 每客户 1 个连接 |
| 可靠性 | 可能丢失或乱序 | 可靠、按序的字节流("管道") |
三个最容易考的差异:
- UDP 客户没有
connect(),TCP 客户有- UDP 服务器没有
listen()/accept()- TCP 的
recv()只读字节,不像 UDP 的recvfrom()还返回地址
第三部分:P2P
十五、纯 P2P 架构
| 特性 | 说明 |
|---|---|
| 无 always-on 服务器 | 没有中心节点 |
| 任意端系统直接通信 | 对等方之间直连 |
| 对等方间歇连接且会换 IP | 这是管理上的主要难点 |
讲义给的三类例子:
| 类别 | 代表 |
|---|---|
| 文件分发 | BitTorrent |
| 流媒体 | Zattoo、KanKan |
| VoIP | Skype |
十六、文件分发时间:C/S vs P2P(最可能出计算题)
问题:把大小为
的文件从一台服务器分发给 个对等方需要多久? 对等方的上传/下载能力是受限资源。
符号约定
| 符号 | 含义 |
|---|---|
| 文件大小 | |
| 服务器上传能力 | |
| 对等方 |
|
| 对等方 |
|
| 最小的客户下载速率 |
客户-服务器
两项各自的来源:
| 项 | 推导 |
|---|---|
| 服务器必须「顺序地」发送 N
份文件副本 发一份要 |
|
| 每个客户都要下载一份完整文件 最慢的那个客户(最坏情况)要 |
P2P
三项各自的来源:
| 项 | 推导 |
|---|---|
| ⚠️ 服务器至少要上传一份副本(注意:不是 N 份!)—— 剩下的靠对等方之间互传 | |
| 每个客户都要下载一份 | |
| 所有客户总共必须下载 最大总上传速率 = |
⚠️ 第一项是最常错的:很多人写成
,那是 C/S 的式子。 P2P 的关键就在于「服务器只需上传一份,剩下的让对等方帮忙散播」。
十七、为什么 P2P 能扩展(核心洞见)
讲义 p29 的原话: 「分子随 N 线性增长……但分母也随之增长,因为每个新对等方都带来了服务能力。」
看第三项的结构:
取极限:
这就是水平渐近线 —— 无论多少个对等方,分发时间不会超过
(即「单个对等方上传完一份文件所需的时间」)。 而 C/S 的 是没有上界的直线。
用讲义 p30
的参数验证( 小时, , )
| C/S 是 P2P 的几倍 | |||
|---|---|---|---|
| 1 | 0.10 | 0.10 | 1.0× |
| 10 | 1.00 | 0.50 | 2.0× |
| 20 | 2.00 | 0.67 | 3.0× |
| 35 | 3.50 | 0.78 | 4.5× |
| ∞ | → 1.00 | ∞ |
两条曲线的形状(讲义 p30 的图):
- C/S 是直线上升,无上界
- P2P 趋于水平渐近线
小时 考试若问「N 很大时 P2P 分发时间趋于多少」,答案就是
。
十八、BitTorrent
背景数字(讲义 p31)
| 项 | 值 |
|---|---|
| 2012 年占欧洲互联网流量 | 20% |
| 典型用途 | Linux 发行版、软件补丁、影片分发 |
| 目标 | 快速地把大文件复制给大量客户 |
核心组件
| 概念 | 说明 |
|---|---|
| torrent | 交换某文件分块的一组对等方 |
| tracker | 追踪参与该 torrent 的对等方(下载者/拥有者) |
| .torrent 文件 | 由 Web 服务器托管,含文件长度、哈希、tracker 的 URL |
| chunk(分块) | 256 KB(讲义 p31 也写 256 kB–1 MB) |
一个对等方的生命周期
| 阶段 | 发生了什么 |
|---|---|
| 加入 | 向 tracker 注册,获得对等方列表,连接其中一个子集("邻居") |
| 初始状态 | 没有任何分块,随时间从其他对等方积累 |
| 下载中 | 同时也在向别人上传分块 |
| 动态调整 | 可能更换交换分块的伙伴 |
| churn(搅动) | 对等方随时来去 |
| 完成后 | 可以(自私地)离开,也可以(利他地)留在 torrent 里当种子 |
两个核心策略(必考)
策略一:请求分块 —— rarest first(最稀缺优先)
| 步骤 | 动作 |
|---|---|
| 1 | 周期性地问每个对等方「你有哪些分块」 |
| 2 | 从对等方请求缺失的分块,最稀缺的优先 |
为什么要最稀缺优先:如果人人都先要最常见的分块,稀缺分块的持有者一旦离开, 整个 torrent 就再也拼不出完整文件了。 优先复制稀缺分块能最大化文件在群体中的可用性。
策略二:发送分块 —— tit-for-tat(一报还一报)
| 规则 | 数值 / 说明 |
|---|---|
| 向谁发送 | 当前以最高速率给她发分块的 4 个对等方(top 4) |
| 其他对等方 | 被「阻塞(choked)」—— 收不到她的分块 |
| 重估周期 | 每 10 秒重估 top 4 |
| 乐观疏通 | 每 30 秒随机选另一个对等方开始发送分块(optimistically unchoke) |
| 结果 | 被乐观疏通的新对等方可能进入 top 4 |
tit-for-tat 的正反馈循环(讲义 p35)
(1) Alice 乐观疏通 Bob |
讲义的结论:上传速率越高 → 找到越好的交易伙伴 → 拿到文件越快。
为什么需要「乐观疏通」这个随机机制: 如果只按 top-4 规则,新加入的对等方(还没有任何分块可上传)永远进不了任何人的 top 4, 就会饿死。 每 30 秒的随机疏通给了他们「起步资金」。
十九、分布式哈希表(DHT)
是什么
DHT 是一个分布式的 P2P 数据库,存储 (key, value) 对。
| 能力 | 说明 |
|---|---|
| 分布存储 | 把键值对分散到许多对等方上 |
| 查询 | 对等方用 key 查询 DHT,DHT 返回匹配的 value |
| 插入 | 对等方也能插入 (key, value) 对 |
讲义的例子:key =
社保号,value = 人名。
DHT 要解决的两个问题
- Assign the keys —— 键值对该放在哪个对等方上?
- Lookup the keys —— 给定 key,怎么找到持有它的主机?
二十、把 key 分配给哪个对等方
基本思路(讲义 p39)
| 步骤 | 动作 |
|---|---|
| 1 | key 生成一个整数 |
| 2 | 给每个对等方也分配一个整数 ID |
| 3 | 把 (key, value) 放在「ID 最接近 key」的对等方上 |
具体做法(讲义 p40)
| 要素 | 说明 |
|---|---|
| 对等方 ID 范围 | |
| key 范围 | 同一个范围 |
| 怎么把原始 key 变成整数 | 用哈希函数 |
哈希函数的定义(讲义原文):把任意大小的数据映射到固定大小数据的函数。 例子:
15 = hash("Led Zeppelin IV")这就是它叫「哈希」表的原因(distributed "hash" table)。
规则:分配给「最接近的 ID」,这里定义为立即后继(immediate successor)
讲义 p41 的例子(
| key | 后继对等方 | 说明 |
|---|---|---|
| 0 | 1 | 大于等于 0 的最小 ID |
| 1 | 1 | 恰好命中某个节点 |
| 2 | 3 | — |
| 13 | 14 | 讲义给的例子 |
| 14 | 14 | 恰好命中 |
| 15 | 1 | ⚠️ 没有 ≥15 的对等方 ⇒ 环回到最小的 1 |
| 16 | 1 | 同样环回 |
⚠️ 「环回」是最常考的边界情况 —— key 超过最大对等方 ID 时,绕回环的起点。
另一个陷阱:「最接近」在这里定义为「立即后继」,不是「数值上最近」。 例如 key = 13 时,节点 12 在数值上更近(差 1),但答案是 14(后继)。
二十一、环形 DHT 与查询代价
基础版:只知道立即后继(讲义 p43–44)
结构:每个对等方只知道自己的立即后继,形成一个环。
讲义 p44 的例子:对等方
0001, 0011, 0100, 0101, 1000, 1010, 1100, 1111
| 问题 | 答案 |
|---|---|
谁负责 key
1110? |
节点
1111 |
| 为什么 | |
| 代价 | 讲义标注沿环传了 6 条消息 |
💡 关于「6 条」的计数口径:沿后继从
0001走到1111要经过 7 个节点间隔, 讲义图上标了 6 个查询消息 —— 差异在于是否计入最后的「I am」应答,或查询从哪个节点发起。 考试记结论即可:基础环形 DHT 平均需要条消息。
改进版:加捷径(讲义 p45–46)
每个对等方记录三样东西:
| 记录 | 作用 |
|---|---|
| successor(后继) | 环上的下一个 |
| predecessor(前驱) | 环上的上一个 |
| shortcuts(捷径) | 跳到远处的节点,加速请求转发 |
效果:同一个查询从 6 条消息降到 2 条(讲义 p46)。
两种版本的复杂度对比
| 节点数 |
||
|---|---|---|
| 8 | 4 | 3 |
| 64 | 32 | 6 |
| 1,024 | 512 | 10 |
| 1,000,000 | 500,000 | ≈ 20 |
这张表说明了为什么必须加捷径:百万节点时,
要跑 50 万跳, 只要 20 跳。
Chord
Chord 是 DHT 的一个具体实例 —— 论文标题: "Chord: A scalable peer-to-peer lookup service for internet applications"
一个 Chord 节点有:后继、前驱、若干捷径。
二十二、处理对等方搅动(Peer Churn)
| 机制 | 说明 |
|---|---|
| 每个对等方知道它「两个」后继的地址 | ⚠️ 不是一个! |
| 周期性 ping 这两个后继 | 检查存活 |
| 若立即后继离开 | 把下一个后继升为新的立即后继 |
讲义 p47 的例子(环:1, 3, 4, 5, 8, 10, 12, 15;对等方 5 突然离开):
| 步骤 | 动作 |
|---|---|
| 1 | 对等方 4 检测到 5 已离开 |
| 2 | 把 8 设为自己的立即后继 |
| 3 | 问 8「你的立即后继是谁」 |
| 4 | 把 8 的立即后继(10)设为自己的第二后继 |
「为什么要知道两个后继而不是一个?」是标准 MCQ: 因为立即后继挂掉时需要立刻有备用,否则环就断了,查询无法继续转发。
💡 讲义还留了个问题:「如果对等方 13 想加入怎么办?」 答案思路:13 的后继应该是 15,前驱应该是 12 —— 需要通知 12 把后继改成 13, 并把原属于 13 范围的 key 从 15 迁移过来。
第四部分:配套 Tutorial —— HTTP Wireshark
⚠️ COMP5416 的 tutorial 比 lecture 慢一周 —— Week 4 模块里的这份 tutorial 练的是 Week 03 的 HTTP。
二十三、Wireshark 的分层视图
HTTP 消息装在 TCP 段里,TCP 段装在 IP 数据报里,IP 数据报装在以太网帧里 —— Wireshark 会同时显示 Frame / Ethernet / IP / TCP / HTTP 五层信息。
操作建议(tutorial 原文):把 Frame、Ethernet、IP、TCP 的三角形收起来(右指), 只展开 HTTP 那一行 —— 减少非 HTTP 信息的干扰。
💡 tutorial 特别提醒:忽略
favicon.ico 的 GET 和响应 —— 那是浏览器自动去问
「有没有小图标显示在地址栏旁边」,与实验无关。
二十四、Exercise 1:基本 GET/响应
| 问题 | 答案 |
|---|---|
| 抓到几条 HTTP 消息 | 2 条:浏览器的 GET + 服务器的响应 |
| 服务器返回的状态码 | 200 |
| HTML 文件上次修改时间 | 不到一分钟前 |
| 返回的内容字节数 | 128 字节(等于 "Line-based txt data" 的长度) |
| 原始数据里有未显示的首部吗 | 没有,所有首部都列出来了 |
「为什么是不到一分钟前」(tutorial 专门解释了):
gaia.cs.umass.edu服务器每分钟把该文件的 last-modified 时间设为当前时间。 所以隔一分钟再访问,文件就显得「刚被修改过」,浏览器会重新下载「新」副本 —— 这个设计正是为了让下一个练习(条件 GET)能观察到两种不同的结果。
二十五、Exercise 2:条件 GET(直接对应 Week 3 的考点)
前提:先清空浏览器缓存(tutorial 要求)。
| 步骤 | 观察结果 |
|---|---|
| 第一次 GET | 没有
IF-MODIFIED-SINCE 行 |
| 服务器第一次响应 | 显式返回了文件内容 |
| 第二次 GET | 出现
IF-MODIFIED-SINCE: 行 |
| 服务器第二次响应 | HTTP/1.1 304 Not Modified,未返回内容
—— 浏览器从自己的缓存加载 |
这正是 Week 03 讲义条件 GET 那一节的实测版本。 做题时能把「第一次无 If-modified-since、第二次有且返回 304」讲清楚就满分。
二十六、Exercise 3:HTTP 认证(重要安全结论)
目标
URL:http://gaia.cs.umass.edu/wireshark-labs/protected_pages/HTTP-wireshark-file5.html
用户名:wireshark-students 密码:network
| 步骤 | 结果 |
|---|---|
| 初次 GET 的服务器响应 | 401 Authorization required |
| 第二次 GET 新增的字段 | Authorization: Basic
后跟一串编码字符 |
实际抓到的串:
d2lyZXNoYXJrLXN0dWRlbnRzOm5ldHdvcms= |
Base64 解码后:
这个 tutorial 最重要的结论(讲义原文的图题就叫 "Password appears in clear text"): 看起来像加密,其实只是 Base64 编码 —— 用户名和密码是明文可恢复的。
格式规律:Basic 认证的编码内容永远是
用户名:密码,中间用冒号分隔。这直接呼应 Week 03 的两个点: 「TCP/UDP 不加密,明文密码穿越互联网」 和 「需要 SSL」。
⚠️ MCQ 陷阱:Base64 是编码(encoding)不是加密(encryption)。
第五部分:MCQ 速查表
DNS
| 项 | 答案 |
|---|---|
| DNS 端口 | 53 |
| 传输协议 | 主要 UDP(大响应/区域传送用 TCP) |
| 根服务器数量 | 13 个(逻辑上) |
| 本地 DNS 服务器 | 不严格属于层级结构;又叫「默认名字服务器」;充当代理 |
| 四种 RR | A(主机名→IP)、NS(域→权威服务器名)、CNAME(别名→规范名)、MX(→邮件服务器) |
| RR 格式 | (name, value, type, ttl) |
| 迭代 vs 递归 | 迭代:告诉你下一个问谁;递归:替你把答案取回来 |
| 两种查询的消息数 | 本例都是 8 条,差别在「谁承担往返」 |
| 缓存性质 | TTL 到期消失;可能过时 ⇒ 「尽力而为」 |
| 不集中式的三个理由 | 单点故障、距离远、可扩展性 |
| NS 记录的伴生记录 | 必须配一条 A 记录(胶水记录) |
套接字
| 项 | 答案 |
|---|---|
| UDP socket 类型 | SOCK_DGRAM |
| TCP socket 类型 | SOCK_STREAM |
| TCP 服务器区分多个客户靠什么 | 源端口号 |
| 谁控制传输层 | 操作系统(应用层才由开发者控制) |
| UDP 服务器有 listen/accept 吗 | 没有 |
| TCP 服务器有几个套接字 | 1 个欢迎 + 每客户 1 个连接 |
| 哪个调用返回发送方地址 | recvfrom()(UDP
独有) |
P2P
| 项 | 公式 / 答案 |
|---|---|
| C/S 分发时间 | |
| P2P 分发时间 | |
| P2P 第一项 | ⚠️ |
| P2P 的 N→∞ 极限 | |
| BitTorrent 分块 | 256 KB |
| 请求策略 | rarest first |
| 发送策略 | tit-for-tat,top 4,每 10 秒重估 |
| 乐观疏通 | 每 30 秒随机选一个 |
| 乐观疏通的作用 | 让没有分块的新对等方不至于饿死 |
DHT
| 项 | 答案 |
|---|---|
| key 分配规则 | 给「立即后继」;超出最大 ID 则环回 |
| 「最接近」的定义 | 后继,不是数值最近 |
| 基础环形 DHT 查询代价 | |
| 加捷径后 | |
| Chord 节点记录什么 | 后继、前驱、捷径 |
| 每个对等方记几个后继 | 两个(应对 churn) |
| 为什么要两个 | 立即后继挂掉时环不至于断 |
最容易错的 6 个点
- P2P 公式第一项是
,不是 - DHT 用「后继」不是「数值最近」;超过最大 ID 要环回
- BitTorrent:10 秒是重估 top 4,30 秒才是乐观疏通
- 本地 DNS 服务器不属于 DNS 层级结构
- NS 记录必须配 A 记录,否则拿到名字也联系不上
- Base64 是编码不是加密 —— Wireshark tutorial 的核心结论
第六部分:本讲在考纲中的位置
| Week | 主题 | 笔记 |
|---|---|---|
| 1 | Introduction | Week 01 |
| 2 | Performance | Week 02 |
| 3 | Applications | Week 03 |
| 4 | DNS and P2P | 本文 |
| 5 | Transport | Week 05 |
| 6 | TCP | ⚠️ Canvas 未发布 |
tutorial 与 lecture 的一周错位:
Tutorial 所在周 练的内容 Week 2(T1 博弈论) Week 1 导论 Week 3(Lab 2 Performance) Week 2 性能 Week 4(HTTP Wireshark) Week 3 的 HTTP —— 见本文第四部分 Week 5(DNS) 本讲的 DNS —— 见 Week 05 笔记第八部分 所以本讲 DNS 部分的配套练习在 Week 5 的 tutorial 里。
配套练习:20 题期中模拟卷 的板块三(Q12–Q16)专测本讲内容。