2221 字
6 分钟
计算机网络入门 1:ping 做了什么:数据如何流动
1970-01-01

计算机网络入门 1:ping 做了什么:数据如何流动#

笔者不是计算机专业出身,如有疏漏,还望各位大佬评论区指正

在执行命令时,输出与笔者不同、比笔者详细都是正常情况,并不是环境配置有误 如果找不到 dig 或其他命令,可以手动安裝

一、实验:ping 一下百度#

执行

ping -c 1 www.baidu.com

示例输出

PING www.wshifen.com (98.98.225.192) 56(84) bytes of data.
64 bytes from 98.98.225.192: icmp_seq=1 ttl=49 time=225 ms
--- www.wshifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 225.124/225.124/225.124/0.000 ms

这里出现了两个奇怪的东西:www.wshifen.com98.98.225.192,在正文中,我们会了解到后者是怎么出现的,在文末拓展阅读中,会对前者进行简要说明

二、ping 做了什么#

首先我们需要知道 ping 的目的是什么,在这个例子中,ping 是用来测试本机跟目标之间的网络是否连通的,为此 ping 向百度发送了一个数据包,并在 225 ms 后收到了百度的回复,那么数据包到底是怎么流动的呢

1. DNS 解析#

在上一章中,我们提到 “IP 用来表示网络位置与具体设备,想要在互联网上定位一个设备,唯一的方式是通过访问 IP”,所以 ping 做的第一件事就是从便于人类记忆的域名解析出能进行访问的 IP,这就是我们看到的 98.98.225.192,我们 ping 百度其实就等效于 ping 这个 IP,直接执行 ping -c 1 98.98.225.192 的效果是完全一致的

那 DNS 解析是怎么进行的呢,我们可以读取 /etc/resolv.conf 来查看 DNS 配置,执行

cat /etc/resolv.conf

输出

# Generated by resolvconf
search ... # 可能没有这行
nameserver 127.0.0.1
nameserver ::1
options ...

可以发现 DNS 服务位于本地,在你的电脑上,nameserver 可能是一个公网 IP,比如 1.1.1.1(cloudflare)、223.5.5.5(阿里) 等,也可能是其他本地进程,比如 Tailscale 的 Magic DNS 等,不论是本地进程还是远程服务,它们做的事情就是帮我们将域名解析成 IP

实际上,对于 www.baidu.com 这样的名称,系统并不会直接进行 DNS 查询,而是遵循 /etc/nsswitch.conf 配置的规则进行解析,可以参考拓展阅读

2. 路由表#

现在我们有了 IP 地址,数据包终于可以发送了,但我们要发给谁呢,我们只知道 98.98.225.192 是百度,但我们还不知道怎么前往这个地址,这时候就是路由表生效的时刻了,执行

ip r

输出

default via 192.168.1.1 dev wlp4s0 ... src 192.168.1.2 ...
192.168.1.0/24 dev wlp4s0 ... src 192.168.1.2 ...
...

这里的每一行都是一个条目,系统会优先匹配更小的子网(更大的前缀长度),default 是最后匹配的条目,因为对应前缀长度 0;回忆上一章的知识,只有前 24 位与 192.168.1.0 相同的 IP 才属于这个子网(192.168.1.x),98.98.225.192 不在子网中,因此走第一行 default 配置

via 192.168.1.1 表示系统需要将这个包发给 192.168.1.1,实际上,这个 IP 对应的往往是家里的路由器;dev wlp4s0 表示系统会用这张网卡发送数据包,src 192.168.1.2 标识了数据包的来源(也就是本机地址),别忘了我们的 ping 还需要接受服务器的回包,那肯定要告诉服务器向谁回复

因此,数据的流向和结构就清楚了,我们需要给具体的数据套上一层壳,上面写着:将来自 192.168.1.2 的 <具体数据> 送往 98.98.225.192;系统将这个包通过网卡 wlp4s0 发送给路由器 192.168.1.1

在这个例子中,我们的源地址 192.168.1.2 其实是内网地址,路由器会将这个地址改写成它所拥有的公网地址,这个过程叫做 NAT,具体的内容会在后续章节中涉及;在这个例子中,尽管 ping 是应用程序,但它使用的是 ICMP 协议(网络层),IP 报文携带的负载也由 ICMP 规定,数据流向基本只涉及到 OSI 模型的 1-3 层

3. 邻居表#

我们已经知道,数据包要交给路由器 192.168.1.1;但在局域网内,只有 IP 还不够。IP 是逻辑地址,可能在不同网络中重复,而且网卡、交换机等 Layer 2 设备并不能直接根据 IP 找到下一跳。在局域网内,真正用来定位设备的是 MAC 地址

在上一章中,我们提到”MAC 地址标识了一个 Layer 2 设备,且 MAC 地址(逻辑上)可以认为不会重复也不会变更,与 Layer 2 设备是一一对应的关系”,在这个例子中,无线网络连接了路由器和无线网卡(可以认为是一条网线插在了网口和路由器 LAN 口之间,实际上有线的 802.3 帧结构跟 WiFi 的 802.11 帧结构不一致,但这超出了本系列的范围),路由器和网卡都有一个 MAC 地址,只要知道这个 MAC,那么网卡就能将数据传递过去了

然而电脑怎么知道局域网内其他设备的 MAC 呢,它会像整个子网广播一条消息:192.168.1.2 的 MAC 是 aa:bb:cc:dd:ee:ff,询问 192.168.1.1 的 MAC 是多少;这个消息会传递给子网内的所有设备,当路由器 192.168.1.1 收到后,就会回复自己的 MAC,这个回复不会广播,只有 aa:bb:cc:dd:ee:ff 能收到,此时,网卡就在之前构建出的 IP 报文的基础上再加上:源 MAC 和目标 MAC,这下终于能通过物理介质将数据包发往路由器了

我们可以查看网卡的 MAC,执行

ip l

输出

2: wlp4s0:...
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
altname ...

这里的 aa:bb:cc:dd:ee:ff 就是网卡的 MAC,而 brd 后面的 ff:ff:ff:ff:ff:ff 是广播 MAC,表示广播到子网的所有设备

在收到 ARP 回复后,操作系统会缓存 IP 到 MAC 的映射,避免反复查询,这就是邻居表,执行

ip n

输出

192.168.1.1 dev wlp4s0 lladdr ff:ee:dd:cc:bb:aa REACHABLE
...

这表示在设备 wlp4s0 上连接的邻居是 192.168.1.1、MAC 是 ff:ee:dd:cc:bb:aa

4. 互联网#

路由器收到数据包后,改写源地址,通过互联网将这个数据包送到百度的服务器 98.98.225.192,百度同样构建了一个数据包,写上:将来自 98.98.225.192 的 <回复数据> 发送给 <NAT 映射后的地址>(路由器的公网 IP);路由器收到数据包后,改写目标地址为 192.168.1.2,送回到我们的电脑上

互联网传递数据的方式不在本系列涉及的范围内,在本系列中,只需知道路由器能在知道目标 IP 的情况下将数据包送往目标即可

5. 构建输出#

ping 计算了一下收到数据包跟发送数据包的时间差,给我们一个输出

64 bytes from 98.98.225.192: icmp_seq=1 ttl=49 time=225 ms
--- www.wshifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 225.124/225.124/225.124/0.000 ms

三、数据如何流动#

flowchart TD subgraph DNS direction LR PROC["本地解析服务"] -.->|查询| NS["DNS Server"] end PING["ping 想发送数据"] --> DNS DNS --> ICMP["ICMP 报文"] ICMP -->|"查路由表"| WL["发送到网卡"] WL -->|"查邻居表或 ARP 广播"| ROUTER["路由器"] ROUTER -->|"NAT"| NET["互联网"] NET --> BAIDU["百度"] BAIDU --> NET2["互联网"] NET2 -->|"NAT"| ROUTER2["路由器"] ROUTER2 --> WL2["发送回网卡"] WL2 --> PING2["ping 解析并输出"]

四、拓展阅读#

1. www.wshifen.com 是什么#

DNS 承担的功能不止有将域名解析为 IP,它还可以将域名解析为另一个域名,这是通过 DNS 服务器的条目类型控制的,A 会将域名解析成 IPv4 地址,AAAA 会将域名解析成 IPv6 地址,CNAME 会将域名解析到另一个域名

执行

dig www.baidu.com

输出

...
;; ANSWER SECTION:
www.baidu.com. 1200 IN CNAME www.a.shifen.com.
www.a.shifen.com. 30 IN CNAME www.wshifen.com.
www.wshifen.com. 300 IN A 98.98.225.192
...

这里就能看到 www.baidu.com 被解析为 www.a.shifen.comwww.a.shifen.com 被解析为 www.wshifen.com,最后 www.wshifen.com 被解析为 IP,这个 IP 并不固定,会根据访问的地区发生变化,也可能有多个 IP 来保证可用性

2. 主机名解析#

www.baidu.com 是一个主机名,baidu.com 是一个域名,主机名通常属于某个域,执行

cat /etc/nsswitch.conf

输出

...
hosts: mymachines files myhostname dns
...

这行的四个单词表示了主机名解析顺序,系统(glibc、nscd等)会依次尝试,其中:

mymachine:查询本机的虚拟机、容器,可以执行 machinectl list 查看

files:/etc/hosts,可以直接 cat 查看

myhostname:主机名,可以执行 hostnamectl 查看

在这个例子中,前三个条目都无法查询到 www.baidu.com,因此落到最后一个 dns

我们已经查看过 DNS 解析的具体配置了(nameserver 127.0.0.1),当走到 dns 这个条目时就会遵循这个配置,我们现在可以看看到底是哪个进程在提供服务(默认 53 端口,端口的概念在后续文章中会有涉及),执行

sudo ss -lunp | grep :53

输出

... users:(("dnsmasq",pid=1895,fd=4))

这说明笔者电脑上,一个名为 “dnsmasq” 的进程在提供 DNS 解析服务,如果要了解它的配置,执行 sudo ps aux | grep 'dnsmasq',其命令行参数中指定了配置文件,但这就远远超出本系列的范畴了,因此略去不谈

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

计算机网络入门 1:ping 做了什么:数据如何流动
https://example.com/posts/network-chapter-1/
作者
suif4599
发布于
1970-01-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录