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,它同时是两样东西:

  1. 一个分布式数据库,实现在许多名字服务器的层级结构
  2. 一个应用层协议 —— 主机与名字服务器通信以完成名字解析

二、为什么不用集中式 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
/ | \
com DNS org DNS edu DNS ← TLD 服务器
/ \ / \
yahoo.com amazon.com poly.edu umass.edu ← 权威服务器
DNS DNS DNS DNS

解析 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)
(dns1.networkutopia.com, 212.212.212.1, A)

自己在权威服务器上创建

(www.networkutopia.com,      212.212.212.22,        A)
(www.home.networkutopia.com, www.networkutopia.com, CNAME)

「NS + A 成对出现」是常考点NS 记录只给出服务器的「名字」dns1.networkutopia.com), 还需要一条 A 记录给出它的「IP」212.212.212.1),否则拿到名字也联系不上 —— 这就是所谓的「胶水记录(glue record)」。


第二部分:套接字编程

十一、套接字基础

套接字:应用进程与端到端传输协议之间的门。

控制权划分(讲义 p15 的图,考点):

┌─────────────────┐
│ 应用(process) │ ← 应用开发者控制
│ ┌─────────┐ │
│ │ socket │ │ ← 门
│ └────┬────┘ │
├────────┼────────┤
│ 传输层 │ ← 操作系统控制
│ 网络层 │
│ 链路层 │
│ 物理层 │
└─────────────────┘
部分 谁控制
应用层 应用开发者控制
传输层及以下 操作系统控制

考点开发者唯一能选的传输层参数就是「用 TCP 还是 UDP」以及少数几个选项, 其余(拥塞窗口、重传定时器等)全在内核里,动不了。

两种套接字对应两种传输服务

套接字类型 传输服务
SOCK_DGRAM UDP:不可靠数据报
SOCK_STREAM TCP:可靠、面向字节流

讲义的示例应用(贯穿 UDP/TCP 两版代码):

  1. 客户从键盘读一行字符,发给服务器
  2. 服务器收到后转成大写
  3. 服务器把改后的数据发回客户
  4. 客户收到并显示

十二、UDP 套接字编程

特点(讲义 p17)

特点 说明
无连接 客户与服务器之间没有「连接」,发数据前无握手
发送方的责任 给每个分组显式附上目的 IP 和端口号
接收方的动作 从收到的分组中提取发送方的 IP 和端口号
可靠性 传输的数据可能丢失或乱序到达

应用视角UDP 在客户与服务器之间提供「字节组(数据报)」的不可靠传输。

交互流程(讲义 p18)

服务器(运行在 serverIP)                客户
──────────────────────── ────────────────────────
socket(AF_INET, SOCK_DGRAM)
bind(port = x)
socket(AF_INET, SOCK_DGRAM)
│ │
recvfrom(serverSocket) ←────────── sendto(serverName, x)
│ │
sendto(clientAddress) ──────────→ recvfrom(clientSocket)
│ │
close()

Python 代码要点(讲义 p19–20)

客户端

from socket import *
clientSocket = socket(AF_INET, SOCK_DGRAM) # 创建 UDP 套接字
message = input('...').encode('utf-8') # 字符串 → 字节
clientSocket.sendto(message, (serverName, serverPort)) # 附上服务器地址+端口
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage.decode('utf-8')) # 字节 → 字符串
clientSocket.close()

服务器端

serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', serverPort)) # 绑定到本地端口
while 1:
message, clientAddress = serverSocket.recvfrom(2048) # 同时拿到客户地址
modified = message.decode('utf-8').upper()
serverSocket.sendto(modified.encode('utf-8'), clientAddress)

三个要注意的细节

  1. 客户端没有 bind() —— 操作系统自动分配一个临时端口
  2. recvfrom() 返回两样东西:数据 发送方地址 —— 这是 UDP 独有的
  3. 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)                客户
──────────────────────── ────────────────────────
serverSocket = socket()
bind(port = x)
serverSocket.listen(1)

connectionSocket = accept() ←──── clientSocket = socket()
(TCP 连接建立) clientSocket.connect((hostid, x))
│ │
recv(connectionSocket) ←───────── send(clientSocket)
│ │
send(connectionSocket) ─────────→ recv(clientSocket)
│ │
close(connectionSocket) close(clientSocket)
(欢迎套接字不关)

Python 代码要点(讲义 p23–24)

客户端

clientSocket = socket(AF_INET, SOCK_STREAM)     # TCP 套接字
clientSocket.connect((serverName, serverPort)) # 建立连接
clientSocket.send(sentence.encode('utf-8')) # 不需要再指定地址!
modifiedSentence = clientSocket.recv(1024)
clientSocket.close()

服务器端

serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('', serverPort))
serverSocket.listen(1) # 开始监听
while 1:
connectionSocket, addr = serverSocket.accept() # 返回「新」套接字
sentence = connectionSocket.recv(1024) # 只读字节,不返回地址
capitalized = sentence.decode('utf-8').upper().encode('utf-8')
connectionSocket.send(capitalized)
connectionSocket.close() # 只关连接套接字

十四、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 个连接
可靠性 可能丢失或乱序 可靠、按序的字节流("管道")

三个最容易考的差异

  1. UDP 客户没有 connect(),TCP 客户有
  2. UDP 服务器没有 listen() / accept()
  3. TCP 的 recv() 只读字节,不像 UDP 的 recvfrom() 还返回地址

第三部分:P2P

十五、纯 P2P 架构

特性 说明
无 always-on 服务器 没有中心节点
任意端系统直接通信 对等方之间直连
对等方间歇连接且会换 IP 这是管理上的主要难点

讲义给的三类例子

类别 代表
文件分发 BitTorrent
流媒体 Zattoo、KanKan
VoIP Skype

十六、文件分发时间:C/S vs P2P(最可能出计算题)

问题:把大小为 的文件从一台服务器分发给 个对等方需要多久? 对等方的上传/下载能力是受限资源。

符号约定

符号 含义
文件大小
服务器上传能力
对等方 的上传能力
对等方 的下载能力
最小的客户下载速率

客户-服务器

两项各自的来源

推导
服务器必须「顺序地」发送 N 份文件副本
发一份要 → 发 N 份要 —— 随 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

(2) Alice 成为 Bob 的 top-4 之一,Bob 回报(给 Alice 发分块)

(3) Bob 成为 Alice 的 top-4 之一

双方都拿到更快的下载速度

讲义的结论上传速率越高 → 找到越好的交易伙伴 → 拿到文件越快。

为什么需要「乐观疏通」这个随机机制如果只按 top-4 规则,新加入的对等方(还没有任何分块可上传)永远进不了任何人的 top 4, 就会饿死。 每 30 秒的随机疏通给了他们「起步资金」。

十九、分布式哈希表(DHT)

是什么

DHT 是一个分布式的 P2P 数据库,存储 (key, value) 对。

能力 说明
分布存储 把键值对分散到许多对等方上
查询 对等方用 key 查询 DHT,DHT 返回匹配的 value
插入 对等方也能插入 (key, value) 对

讲义的例子key = 社保号,value = 人名。

DHT 要解决的两个问题

  1. Assign the keys —— 键值对该放在哪个对等方上?
  2. 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 的例子,对等方 1, 3, 4, 5, 8, 10, 12, 14):

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
为什么 最小的 ≥14 的节点 ID 是
代价 讲义标注沿环传了 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 认证(重要安全结论)

目标 URLhttp://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 个点

  1. P2P 公式第一项是 ,不是
  2. DHT 用「后继」不是「数值最近」超过最大 ID 要环回
  3. BitTorrent:10 秒是重估 top 4,30 秒才是乐观疏通
  4. 本地 DNS 服务器不属于 DNS 层级结构
  5. NS 记录必须配 A 记录,否则拿到名字也联系不上
  6. 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)专测本讲内容。