数字营销 · Web开发 · 基础设施

子网掩码到底是什么?先别急着填 255.255.255.0

从实际的数据传输过程出发,简单讲讲 IP、MAC、ARP 和子网掩码之间的关系,以及子网掩码到底在网络通信中起什么作用。

我们在网络配置中,设置路由器或者配置静态 IP 地址时,经常会遇到很重要的一步:设置子网掩码。很多人习惯性地填上 255.255.255.0,至于它到底是什么意思,可能还真没仔细想过。

Windows系统的网络配置
Windows系统网络配置

如果去互联网上查资料,通常也很难一下看明白。上来就是“网络位”“主机位”“二进制转换”之类的一堆概念,看着就有点头大。

熟悉我的朋友可能知道,我大学虽然学的是管理学专业,但曾经立志从事网络行业,所以花“重金”学习过思科 CCNA。对局域网、广域网、路由、交换这些东西,都系统地学习过,也认真折腾过。

这么多年过去,广域网的一些知识因为缺少实践,已经逐渐遗忘了。但平时工作中,我依然经常接触局域网、服务器和各种网络设备,有些东西反而因为长期实践,理解得比以前更深。

而在给企业配置网络的过程中,我也发现,即使是经常接触网络设备的人,对子网掩码到底是怎么回事,也未必真的理解。

所以这篇文章,尝试用我自己的理解,聊聊子网掩码到底是什么。

网络数据是怎么传输的

OSI 七层模型把网络通信划分成物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。但实际使用的网络体系更多是 TCP/IP 模型,它把一些层进行了合并,结构也更加简单。不管采用什么模型,我们不妨直接看看,一段数据到底是怎么发出去的。

OSI七层模型和TCP/IP模型对比
OSI七层模型和TCP/IP模型对比

假设我们打开浏览器,访问 http://www.hitoy.org。

首先,浏览器通过 DNS 查询 www.hitoy.org 对应的 IP 地址,然后与服务器的 80 端口建立 TCP 连接。

连接建立后,浏览器生成 HTTP 请求数据:

GET/ HTTP/1.1
Host: www.hitoy.org
User-Agent: curl

接下来,这段数据交给操作系统的网络栈。网络栈就像给一封信一层一层加“信封”:传输层加上 TCP 信息,网络层加上 IP 信息,数据链路层再加上 MAC 信息。最后,这些数据交给网卡,转换成电信号、光信号或者无线信号,真正发送出去。

TCP、IP 和以太网逐层封装网络数据的示意图
TCP、IP 和以太网逐层封装网络数据的示意图

对于一个准备发送的数据包来说,应用程序(浏览器)已经确定了目标 IP 地址和端口号,那么问题来了:数据链路层需要的 MAC 地址,又是从哪里来的?

ARP 与 MAC 地址

在局域网(以太网)中,如果设备不知道某个 IP 对应的 MAC 地址,就会通过 ARP(地址解析协议)查询。系统会在局域网中发送一个 ARP 广播,拥有这个 IP 的设备收到后返回自己的 MAC 地址,系统再把这个对应关系缓存起来。整个过程由操作系统网络栈完成,应用程序不需要参与。

Windows上的ARP缓存
Windows上的ARP缓存

不过,如果目标 IP 不在当前局域网,就不能直接 ARP 查询目标设备的 MAC,而是应该把数据交给网关。那么,系统怎么知道目标 IP 是不是在本地网络?

这时候就用到了子网掩码。

子网掩码如何工作

网络栈会把本机 IP 和目标 IP,分别与子网掩码进行二进制按位 AND 运算。比如:

本机 IP:   192.168.1.10
目标 IP: 192.168.1.20
子网掩码: 255.255.255.0

把每一位转换成二进制后进行 AND:

第1段第2段第3段第4段
本机 IP192 11000000168 101010001 0000000110 00001010
子网掩码255 11111111255 11111111255 111111110 00000000
运算结果19216810

所以:

192.168.1.10 AND 255.255.255.0 = 192.168.1.0
192.168.1.20 AND 255.255.255.0 = 192.168.1.0

两个结果相同,就说明它们属于同一个网络。

如果目标是 8.8.8.8:

8.8.8.8 AND 255.255.255.0 = 8.8.8.0

结果不同,就说明目标不在当前网络,需要把数据交给网关。

所以,子网掩码其实就是一个筛子:通过二进制 AND 运算,把 IP 地址中用于表示网络的部分“筛”出来,然后比较本机和目标是不是属于同一个网络。

再理解网络位和主机位

讲到这里,又绕不开“网络位”和“主机位”。这是从网络层来理解的,简单来说,网络位就是网络的 ID,主机位就是这个网络里具体主机的 ID。同一个网络里的主机,通常可以直接进行二层通信;如果目标不属于这个网络,就需要通过网关转发。

这样说可能还是有点抽象,我们换个角度,从数据链路层来看,就很好理解了。

当网络栈拿到一个网络层的 IP 数据包时,数据包里已经有了目标 IP 地址。这时候,网络栈要做的事情其实很简单:

这个数据包,是直接发给目标主机,还是发给网关:如果目标 IP 和本机属于同一个网络,就需要找到目标主机的 MAC 地址,然后把这个 MAC 地址写进以太网帧头;如果目标 IP 不属于本地网络,就找到网关的 MAC 地址,把网关的 MAC 写进帧头。

而判断的方法,就是利用本机的 IP 地址 + 子网掩码,与目标 IP 地址进行比较,所以从这个角度看,子网掩码其实一点都不神秘。它只是帮助网络栈判断:目标 IP 属不属于“我这个网络”?

属于,就直接找目标主机的 MAC;不属于,就找网关的 MAC。

总结

应用程序通过 socket 等系统接口,指定通信的目标 IP 和端口。协议栈根据应用程序提供的数据、端口和 IP,一层层封装成数据包。

到了数据链路层,需要知道这个数据帧应该发往哪里。协议栈会根据本机 IP、子网掩码和目标 IP进行计算:如果目标在本地网络,就查找目标主机的 MAC;如果不在本地网络,就使用网关的 MAC。

从二层的角度看,子网掩码其实就这么简单:它帮助协议栈确定网络边界,从而决定数据是直接发给目标主机,还是交给网关。

所以,255.255.255.0 并不是一个需要死记硬背的“标准答案”,只是最常见的一种子网掩码而已。

评论0

欢迎分享你的看法,也欢迎补充不同的实践经验。