TCP/IP 学习笔记:IPv4、子网掩码

学习资料:《TCP/IP详解卷1:协议》

1# 点分四组(点分十进制)表示法

IP 地址通常使用点分四组表示法来表示,实际上是四个非负8位二进制数,所以范围是 [0, 255]。

点分四组表示 二进制表示
0.0.0.0 00000000 00000000 00000000 00000000
1.2.3.4 00000001 00000010 00000011 00000100
192.168.0.1 11000000 10101000 00000000 00000001
255.255.255.255 11111111 11111111 11111111 11111111

2# 五类 IPv4 地址空间

n 为 网络号,h为主机号
A类地址:0nnnnnnn hhhhhhhh hhhhhhhh hhhhhhhh,范围是 [0~127].h.h.h
B类地址:10nnnnnn nnnnnnnn hhhhhhhh hhhhhhhh, 范围是 [128~191].[0~255].h.h
C类地址:110nnnnn nnnnnnnn nnnnnnnn hhhhhhhh, 范围是 [192~223].[0~255].[0~255].h
D类地址是组播地址,以 1110 开头,范围是 [224~239].x.x.x
E类地址是保留地址,以 1111 开头,范围是 [240~255].x.x.x

A、B、C 类地址为单播地址,是最常见的网络地址。

A类地址网络号总共只有127个,但每个网络号下面有 224 个主机号是可用的。
C类地址网络号有200万+,但每个网络号下面就只能容纳256台主机(抛开不可用的首尾地址只有254台主机)。

3# 子网寻址

例如一个站点已经获得了一个B类地址(前16位为网络号),那么后十六位可能被该站点的网络管理员用于划分子网。
假设这个站点分配的网络号为 128.32.x.x,该站点的网络管理员可能将其划分为 128.32.子网号.主机号 ,这样本来是 1 个网络,其中有 65535 - 2 台主机的网络,就被分成了 256 个子网,每个子网下有 254 台主机。

这么划分可以更好地组织和管理站点的网络,但对于 Internet 来说,仍然将它视为站点相关的地址来看待。

4# 子网掩码

假设这个站点 128.32.子网号.主机号 目前使用了两个子网号,128.32.1.x128.32.2.x ,那么站点的 边界路由器 需要连接 Internet 和两个子网(内部局域网)。
Internet 上所有发给该边界路由器的 接口地址(公网IP) 的流量均由 Internet 路由系统直接发给这个边界路由器,然后边界路由器会把属于 128.32.1.x128.32.2.x 这两个子网号 的流量分别转发给两个子网。

这个站点两个子网如下:

128.32.1.x = 10000000 00100000 000000001 hhhhhhhh
128.32.2.x = 10000000 00100000 000000010 hhhhhhhh

那么边界路由器如何知道哪些位是子网的网络号,哪些位是主机号呢?

子网掩码就是用来区分子网号和主机号的。子网掩码长得和 IP 地址几乎一摸一样,但以二进制表示的时候 遵循网络号全为1,主机号全为0的规律 。由于 IP 地址一定是 前面为网络号后面位主机号 ,所以子网掩码一定是一串 1 加上一串 0 的形式。

128.32.子网号.主机号 这个站点的子网掩码就应该设置为 11111111 11111111 11111111 00000000,表示前面三个八位二进制数为网络号,后面一个八位为主机号,转换为点分四组表示法则是 255.255.255.0

设想一个包到达了边界路由器,目标地址是 128.32.2.135 ,那么路由器会先寻找目标的子网号,过程如下:

128.32.2.135 = 10000000 00100000 00000010 10000111
255.255.255.0 = 11111111 11111111 11111111 00000000
位与计算结果 = 10000000 00100000 00000010 00000000 = 128.32.2.0

得出子网号为 128.32.2.0位与 计算可以在 我的另一篇博客 中了解。

那么子网号一定需要占够八位吗?不一定。假设该站点的网络管理员认为,该站点只需要 4 个网络号即可,每个网络需要超过254台主机,那么可以将子网掩码设置为 11111111 11111111 11000000 00000000 点分四组表示为 255.255.192.0 那么站内的四个子网即为:

128.32.[0~63, 64~127, 128~191, 192~255].x

这种情况下,假设一个包到达了边界路由器,目标地址是 128.32.135.77,寻找目标的子网号过程如下:

128.32.135.77 = 10000000 00100000 10000111 01001101
255.255.192.0 = 11111111 11111111 11000000 00000000
位于计算结果 = 10000000 00100000 10000000 00000000 = 128.32.128.0

1
2
3
4
5
6
7
8
9
ip = '128.32.135.77'.split('.', -1)
sm = '255.255.192.0'.split('.', -1)
result = []

# 分别对四组进行位于计算
for i in range(4):
result.append(int(ip[i]) & int(sm[i]))

print('{}.{}.{}.{}'.format(*result))
128.32.128.0

即完成了子网寻址。

既然子网掩码是由前面一串1定义子网号,后面一串0定义主机号的,那么可以使用另一种称之为 前缀表示法 的方式来表示,例如:

255.255.192.0 = 11111111 11111111 11000000 00000000,前面有 18 个 1,故可写为 /18。对于上例的完整的前缀表示法则为 128.32.135.77/18 ,表示此 IP 的前 18 位为子网号,后 32 - 18 = 14 位为主机号。

子网掩码纯粹是站点内部(边界路由器之内)的局部问题,因为站点外的路由器进行路由过程时只基于地址的网络号,并不需要子网号和主机号部分。

0%