Wireshark 抓到第 47 个包的计算机网时候,我盯着屏幕愣了几秒。络实源地址 192.168.1.6,验报目标 10.0.0.3,计算机网协议栏写着 ICMP,络实但 Type 字段是验报 3,Code 也是计算机网 3。端口不可达。络实这不对——我 ping 的验报是另一台主机的 80 端口,按理说要么通,计算机网要么超时,络实怎么会弹回一个端口不可达?验报
后来翻 RFC 792 才搞明白,ICMP 差错报文里 Type 3 Code 3 表示“目标端口不可达”,计算机网通常是络实目标主机回复的。但这里源地址是验报 192.168.1.6,也就是我自己的机器。说明路由器在转发时发现目标端口没有服务监听,直接替我回了。这个细节课本上没讲,抓包才看见。
这学期计网实验一共六个,我印象最深的是第三个——用 socket 写一个简易的 HTTP 服务器。老师给了个框架,核心逻辑要自己填。我一开始想偷懒,直接用 Python 的 http.server 模块,两行搞定。但助教检查时问了一句:你知道 200 OK 后面那个 Content-Length 怎么算的吗?我答不上来。
于是老老实实从 socket 开始写。bind、listen、accept,然后 recv 收请求,解析请求行和头部,再拼响应。第一次跑的时候,浏览器一直转圈,不显示页面。抓包发现我发的响应少了空行——HTTP 头部和 body 之间必须有一个 \r\n\r\n,我只写了 \n。就这一个字符,浏览器解析不了,连接一直挂着。改完再试,页面出来了,但中文全是乱码。忘了在 Content-Type 里加 charset=utf-8。这些问题不亲手踩一遍,光看教材根本记不住。
实验四做子网划分。给定一个 C 类地址 192.168.10.0/24,要分成 6 个子网,每个至少容纳 25 台主机。我拿纸笔算:2 的 n 次方减 2 要大于等于 25,n 最小是 5,也就是主机位留 5 位,子网位借 3 位。那子网掩码就是 /27,255.255.255.224。每个子网 32 个地址,可用 30 个。6 个子网需要 3 位子网号,刚好 8 个,够用。算完挺得意,结果 ping 测试时发现第一个子网和第二个子网之间不通。查了半天,原来是我把网关地址配成了子网的网络地址——.0 是网络号,不能用。这种低级错误,不实际配一遍根本不会当回事。
实验五用 Cisco Packet Tracer 配静态路由。三台路由器串成一条线,左边一个 PC,右边一个 PC,要求互通。我按教程一步步配,ip route 命令写得没问题,但就是 ping 不通。show ip route 一看,路由表里只有直连路由,静态路由没生效。后来发现是下一跳地址写错了——我写的是对方接口的 IP,但那个接口在另一个网段,路由器根本找不到。应该写自己直连接口的对端地址。这个弯绕得我晚饭都没吃好。
最折腾的是实验六,抓 TCP 三次握手。我在虚拟机上跑了个 Apache,然后用另一台机器 curl 访问,同时开 Wireshark 抓包。第一次抓到的全是 ARP,因为 ARP 缓存过期了。等 ARP 解析完,终于看到 SYN、SYN-ACK、ACK。但奇怪的是,SYN 包的窗口大小是 29200,SYN-ACK 是 28960,到了 ACK 又变成 29200。查资料才知道,窗口大小在握手阶段可以协商,接收方会根据缓冲区调整。这种动态变化,课本上就一句话带过,实际看到序列号的变化才有感觉。
六个实验做完,最大的收获不是学会了配路由或者写 socket。是养成了一个习惯:遇到不通,先抓包。ping 不通?抓包看 ICMP 有没有回来。网页打不开?抓包看 TCP 有没有建立。DNS 解析失败?抓包看 UDP 53 端口有没有响应。数据包不会骗人,它把每一步都摊在你面前,就看你能不能读懂。
昨天帮同学调一个网络问题,他描述了半天“就是连不上”,我直接说:你抓个包发我。五分钟后他发来截图,我一看,TCP 重传了三次,每次间隔翻倍——典型的丢包。让他换根网线,好了。他问你怎么知道的,我说包告诉我的。这大概就是这门课留给我最实用的东西。
顶: 6482踩: 7876






评论专区