计算机从「一台机器干一件事」变成了「一台机器干十件事」,联网方式也跟着变多了。 这一节先把「多样化」落到可数的东西上:一台普通电脑里到底有几张网卡。
这是全书第一节,先把「网络」这个词从抽象拉到具体。 1.1.2 会把话题往前推一步:有了这么多能通信的机器,为什么还要「互连」。
一、从「一台机器」到「几张网卡」
书上讲的多样化,是指计算机的用途从科学计算扩散到办公、娱乐、工业控制。 用途一多,连接方式就一多——同一台机器上要同时有有线、无线、蓝牙、虚拟网卡。
数一数就知道这句话不是修辞:
| 接口 | 用途 | 典型速率 |
|---|---|---|
| 以太网 | 插网线,最稳 | 100/1000/2500 Mbps |
| WLAN | Wi-Fi 无线接入 | 常见 72/144/300 Mbps |
| 蓝牙网络连接 | 连手机、耳机 | 低速,几 Mbps |
| 回环 | 自己跟自己说话 | 内存速度 |
| 虚拟网卡 | 虚拟机、VPN、热点 | 跟着上层走 |
第一行那个「最稳」不是主观评价:有线是全双工独占,无线是共享介质、还要抢信道, 这是 3.2 节要展开的区别。
二、网卡对操作系统是什么
不管物理还是虚拟,操作系统看到的都是一个「接口」(interface)。 接口要能被使用,得有三样东西:
| 东西 | 例子 | 没有它会怎样 |
|---|---|---|
| 名字 | WLAN、以太网 |
命令行没法指定它 |
| 硬件地址 | 9C-B6-D0-0D-D5-0F |
同网段内认不出谁是谁 |
| 一个 IP 与掩码 | 192.168.3.152/24 |
跨网段没法路由 |
第三行那个 /24 是掩码的简写:255.255.255.0 里有 24 个 1,所以写 /24。
这种写法叫 CIDR,4.3.7 会专门讲,这里先认个脸。
三、169.254 是什么地址
网卡列表里最容易让人困惑的是 169.254 开头的地址。 它不是谁分配的,是网卡自己挑的—— 开机后先广播问「有没有 DHCP 服务器」,问不到就自己从 169.254.0.0/16 里挑一个。
这个机制写在 RFC 3927 里,名字叫 APIPA(自动专用 IP 寻址)。 它的用处只有一个:让同一个网段里的两台机器在「没有任何服务器」的情况下也能互相通信。
但它的坏处更明显:169.254 开头的地址是「我连不上 DHCP」的标志, 看到它就知道这张网卡此刻没法正常工作。 排障时第一眼要看的就是这个——比 ping 任何东西都快。
四、动手 Demo:数一数本机有几张网卡,各自是什么状态
用 psutil 把本机所有网络接口、硬件地址、MTU、速率读出来, 并按「在用/未连接/APIPA 自配/回环」分类。 最后两列是判读结果,不是原始数据——判读规则写在代码里,可以改。
import psutil, socket
addrs = psutil.net_if_addrs()
stats = psutil.net_if_stats()
for name in sorted(addrs):
st = stats.get(name)
mac = ipv4 = mask = u''
for a in addrs[name]:
if a.family == psutil.AF_LINK and not mac:
mac = a.address
elif a.family == socket.AF_INET and not ipv4:
ipv4, mask = a.address, a.netmask
kind = u'回环' if name.startswith('Loopback') else \
u'APIPA 自配' if ipv4.startswith('169.254.') else \
u'在用' if st and st.isup else u'未连接'
print(u'%-22s %-4s %-18s MTU=%-5d %-6d %s'
% (name, u'是' if st and st.isup else u'否',
mac or u'-', st.mtu if st else 0,
st.speed if st else 0, kind))
实跑输出:
--------------------------------------------------------------------
本机有几张网卡,各是什么类型
--------------------------------------------------------------------
**这台机器一共 6 个网络接口,其中 2 个处于「已连接」状态。**
接口 通 MAC MTU 速率 判读
-----------------------------------------------------------------------------------
Loopback Pseudo-Inte 是 — 1500 1073 回环
WLAN 是 9C-B6-D0-0D-D5-0F 1500 144 在用
以太网 否 28-F1-0E-18-FA-25 1500 — APIPA 自配
本地连接* 1 否 9E-B6-D0-0D-D5-0F 1500 — APIPA 自配
本地连接* 2 否 AE-B6-D0-0D-D5-0F 1500 — APIPA 自配
蓝牙网络连接 否 9C-B6-D0-0D-D5-10 1500 3 APIPA 自配
**「计算机的多样化」在网卡列表里看得很清楚**:
**同一台机器上既有 Wi-Fi、也有蓝牙、还有一堆「本地连接*」的虚拟网卡**——
它们对操作系统来说都是同一个东西:一个能收发帧的接口。
**注意那四个 169.254 开头的地址**:
**这不是谁分配的,是网卡连不上 DHCP 服务器时自己挑的**(RFC 3927)。看地址就知道它此刻不通。
表里 Loopback 的速率显示 1073,这不是真的有 1 Gbps——回环不走物理介质, 这个数是驱动随手填的。 真正要注意的是那四行 169.254:它们都是「连不上 DHCP」的网卡,其中两张是虚拟网卡, 本来就没人给它发地址。 判读规则里有个顺序问题: 先判回环、再判 APIPA、最后判通断——顺序反了,回环就会被判成「在用」, 因为回环确实一直是 up 的。
30 秒实验
- 把
sorted(addrs)换成addrs,看输出顺序变不变,再想想为什么字典顺序每次运行可能不同。 - 把判读规则里的
169.254.改成192.168.,看你的机器上判读结果怎么变。 - 加一行打印
len(n['ipv6']), 看 WLAN 上有几个 IPv6 地址——为什么一块网卡会有四个? 4.6 节会讲。
常见误区
- 以为网卡数量等于网线口数量。 虚拟网卡也算,装一个 VPN 客户端就多一张, 装一个虚拟机软件再多两张。
- 以为 169.254 是「保留地址所以不安全」。 它只是「没拿到地址」的意思,与安全无关; 真正的问题是它出不了本网段。
- 以为回环也要经过网卡。 回环全程在协议栈内部,数据不出网卡、 不上网线——所以它测不出真实网络时延。
自测三问(点开对答案)
1. 一台机器有 6 个网络接口,其中 4 个是 169.254 开头的地址,这说明了什么? —— **这 4 张网卡都没拿到 DHCP 地址**。可能是没插网线、没连 Wi-Fi,也可能是 DHCP 服务不可达。 **判据是地址段,不是接口名。** 2. 回环接口的「速率」显示 1073 Mbps,这个数有意义吗? —— **没有实际意义**。回环不走物理介质,这个字段是驱动填的占位值。**要看回环性能得直接测往返。** 3. 为什么判读规则里「先判回环」很重要? —— **因为回环一直是 up 状态**。 如果把「是否 up」放在最前面判,回环就会被标成「在用」,读者会误以为它是一张真实网卡。下一节往前推一步:既然一台机器上有这么多接口,那「不联网」和「联网」到底差在哪。
- ☐ (本节完,下一节 1.1.2 从独立模式到网络互连模式)