HIT-计算机网络 | 从一次 HTTP 请求出发,我把缓存、丢包和路由都抓了一遍
计算机网络实验最容易让人产生一种错觉:数据从这里发出去,最后从那里收到,似乎只要两端程序写对了,事情就结束了。可真正抓包、模拟丢包、写代理和做 IP 转发以后,我才发现,中间那一长段“看不见的路”才是网络最有意思的地方。
这个仓库里的四个实验,刚好从应用层一路走到网络层:HTTP 代理和缓存、GBN/Selective Repeat 可靠传输、IPv4 收发与最长前缀匹配,以及 Wireshark 协议分析。它们让我不再把网络理解成一个抽象的“发送函数”,而是开始注意请求、报文、确认、超时、路由和抓包里每一个细节。
仓库地址:HIT-Computer-Networks-Labs。
实验一:写一个 HTTP 代理,第一次亲手改请求和响应
HTTP 代理是这组实验里最容易让人产生“我已经懂网络了”错觉的部分。浏览器先把请求交给代理,代理再去访问目标服务器,把结果转回来。听起来只是多了一站,但一旦加入缓存、重定向和站点阻断,代理就不再是简单的转发器。
项目里的缓存会保存 URL、Host、Last-Modified、状态码和响应内容。第一次访问时,代理把服务器结果存下来;第二次访问同一 URL,则尝试带上 If-Modified-Since。如果服务器返回 304 Not Modified,代理就可以直接使用本地缓存。
我第一次看到 304 时,感觉它很像服务器在说:“我知道你要的东西,你那边已经有了,不用再给你一份。”以前我只把缓存理解成“存下来下次用”,这次才开始注意缓存需要验证新旧,否则它很快会变成一份过期的答案。
代理还支持对指定站点做阻断和重定向。这个功能让我意识到,网络程序并不只是被动搬运数据,它可以观察并修改请求行为。当然,这个实验级代理不支持现代 HTTPS 代理,也没有实现完整的 HTTP 语义,它的价值主要在于把请求头、状态码和缓存条件暴露出来。
实验二:GBN 和 Selective Repeat,丢包以后谁来负责补救
可靠传输实验把我从“请求能不能到达”带到了“丢了以后怎么办”。在不可靠的传输环境里,发送方不能假设每个包都能顺利抵达、每个 ACK 都能及时回来。
GBN 的思路比较直接:发送方维护一个窗口,出现超时以后,从出问题的位置开始重发后面的数据。它实现起来相对清楚,但如果只是某一个包丢了,后面的包其实可能已经到达,重新发送一大片数据会带来额外开销。
Selective Repeat 则更细致:哪个包丢了就补哪个,接收方也需要缓存已经到达但暂时不能交付的数据。它更节省重传,却需要维护更多状态。窗口、序号、ACK、超时和缓存,每一个小地方都可能让程序在某种丢包顺序下卡住。
我做这个实验时最深的感受是,协议设计的难点不在于“正常情况怎么走”,而在于异常情况到底能不能收回来。包乱序了怎么办?ACK 丢了怎么办?同一个包重发两次怎么办?如果只用一条成功路径测试,程序看起来很容易正确。
| 机制 | 遇到丢包时的反应 | 我感受到的取舍 |
|---|---|---|
| GBN | 从缺失位置开始批量重传 | 逻辑相对简单,但可能重复发送很多数据 |
| Selective Repeat | 只重传确认缺失的包 | 更高效,但状态和缓存管理更复杂 |
实验三:IPv4 收发和最长前缀匹配,路由表不是一张普通字典
IPv4 实验继续往下走,涉及数据包收发、校验和以及最长前缀转发。这个实验让我第一次比较具体地看到,一个包要被送到哪里,并不只是查一个完整的目的地址。
路由器可能同时有多个匹配项,最终要选择前缀更长、匹配更具体的那一条。也就是说,192.168.1.x 比 192.168.x.x 更具体,路由选择需要在所有候选项里找到最长的匹配前缀。
校验和也让我重新理解了“数据包不是一段透明的字节”。首部字段、长度、校验和和地址变化都可能影响转发结果。源码依赖课程提供的外部测试平台,不能简单地在仓库目录里一条命令链接运行,但正因为环境不完整,我反而更清楚哪些部分属于实验实现,哪些部分依赖外部网络模拟器。
实验四:Wireshark,把课本上的协议抓到眼前
Wireshark 实验是这组课程里最有现场感的部分。以前看到 TCP 三次握手、HTTP POST、ARP request 和 reply,都是文字描述;真正打开抓包结果以后,协议不再是背诵题,而是一串按照时间排列的事件。
HTTP 请求里能看到 200 OK,缓存未变化时则可能看到 304 Not Modified。TCP 里能看到 SYN、SYN-ACK 和 ACK,随后才是实际的数据段。IP 层可以观察 TTL、Identification、首部长度、分片和 ICMP TTL exceeded。ARP 则可以通过 OP 字段区分 request 的 0x0001 和 reply 的 0x0002。
我最喜欢抓包实验的一点,是它会迫使你把“先发生什么、后发生什么”讲清楚。一个页面打开很快,但抓包里其实包含了很多小步骤;一个请求失败,也不一定是应用代码错了,可能是 DNS、TCP 连接、路由或对端响应出了问题。
报告里还记录过一次抓包吞吐量估算,约为 92193.6 Bps。这个数字属于当时的实验环境和一次历史抓包,不能当成当前网络性能结论,但它让抽象的“吞吐量”有了可计算的对象。
四个实验连在一起,网络开始有了层次
HTTP 代理让我先从应用层观察请求和响应;GBN/SR 让我自己处理可靠传输;IPv4 实验把注意力带到首部、校验和和路由;Wireshark 则把这些概念放回真实报文里验证。
它们连起来以后,我才逐渐理解分层不是把问题切碎,而是让不同层各自承担责任。应用层关心请求的含义,传输层关心可靠性和顺序,网络层关心寻址和转发,抓包工具则帮助我们观察这些机制如何一起工作。
现在回头看,最容易漏掉的是异常路径
网络程序的正常路径往往很顺:发包、收包、解析、返回。真正决定实现质量的,是丢包、乱序、超时、缓存过期、校验失败和路由不匹配这些情况有没有被认真处理。
我以前写实验时也会本能地先把“能跑”的路径完成,再补错误情况。做完这组网络实验以后,我更愿意在一开始就列出可能失败的地方。因为网络世界里,失败不是偶发的边界,而是默认存在的环境。
仓库地址:HIT-Computer-Networks-Labs。里面保留了四组实验报告、源码和课程材料说明,也写明了历史抓包和外部测试平台的限制。
说明:本文根据个人历史课程实验和公开仓库整理,部分文字经过 AI 辅助润色;抓包数字和运行结果属于历史实验记录。课程资料仅用于学习回顾和个人作品整理,不用于当前课程作业或考试。

浙公网安备 33010602011771号