IP 地址体系(IPv4)
前言
入门网络通信的第一步,自然是IP地址体系。IP这个概念在网络通信中十分重要,是通信能否建立的必须前提。在现实世界里,我们要寄一封信,必须在信封上写清楚地址——哪个省、哪个市、哪条街、几号门。网络通信中也是一样的,每个设备都有自己的一个“门牌号”,数据包从你家送到他家,靠的就是这个地址。
要准确的送达数据包,在网络环境中每个设备就必须有一个唯一地址,这个地址就是IP地址。
IP地址分为 IPv4 与 IPv6,目前主流的依然是IPv4,本文所述的IP地址体系也是基于IPv4进行的。
IPv4地址由32位二进制组成,每个字节(8位)划分成一段,采用点分十进制书写便于阅读(例如:192.168.1.10)。一个IP地址内部包含两层信息:网络号与主机号。
网络号有点类似于小区中的楼栋,每一个网络号对应一个网络地址,也就是小区中的一个单元楼。楼里面有许多房间,每个房间就住着一个主机,也就是我们所说的主机号。同一单元楼的主机可以互相“串门”,但是不同单元楼的主机如果需要互相通信,则需要找门卫,也就是我们所说的网关代为传达。这里我们是以现实中小区进行一个比拟便于理解,实际行为也确实是这样的。
下面就以此为基础,详述IPv4的地址体系。
IPv4地址体系
IPv4地址的表示
地址的表述我们在前言其实已经讲过了,这里再说明一下。IPv4地址本质是一个 32位无符号整数:
1 | |
为了便于表示,我们将其每字节隔开,采用点分十进制表述如下:
1 | |
IPv4 地址总量有 2^32 = 4,294,967,296,约合 42.9亿。别看这么多,目前是已经枯竭了的,当前网络环境普遍采用了NAT技术来重映射IP地址,并划分公网与私网段。
关于该技术详见:NAT 地址转换。
IPv4相关核心概念
在详细了解IP地址之前,需要先厘清几个概念:
网络号与主机号:一个IP地址会被子网掩码划分为两个区域,分别为网络号和主机号。当IP地址中主机号全为0时,其代表的就是网络地址,标识的是整个网段的起始地址。主机号就是该网段中某一设备的编号。
子网掩码是目前划分网络地址与主机地址的“度量衡”。在当前网络环境中,普遍使用的是CIDR无类地址(详见下文)划分机制,其子网掩码可以按如下形式表示:
1 | |
知道子网掩码后,我们就可以给出精确的网络地址与主机地址的划分机制:
使用IP地址与子网掩码进行与(&)运算,其运算结果就是网络地址。
例如:
1 | |
主机号自然就是剩下的8位,总共就2^8 = 256个主机地址。值得注意的是:子网掩码还用来区分网段。如何确定两个设备是否处于同一网段?就用两个设备的IP地址分别去与(&)上子网掩码,若与出来的网络地址相同则说明两个设备处于同一网段。
广播地址是主机号全为1的地址,其作用是向本网段内所有设备广播数据。广播地址是一个特殊的地址,不能单独分给某一个设备。例如上述示例中:192.168.43.0这个网段的广播地址就在192.168.43.255。当该网段内某个设备向该地址发送一个数据包后,整个地址位于192.168.43.x(x!=0 && x!= 255)都能够收到该包数据。
可用主机范围是该网段中,所有能够划给使用使用的具体IP地址的一个范围。这其中需要剔除掉本网段广播地址与网络地址。例如在192.168.43.x网段中,需要剔除掉192.168.43.0(网络地址)和192.168.43.255(广播地址)。剩下的可分配地址范围为192.168.43.1~192.168.43.254,这就是可用的主机地址范围。
网关:网关是出网段的“大门”,不同网段之间需要通信必须经过网关转发。同时,网络拓扑有本地局域网与公网之分,本地局域网中的设备想要与公网服务器进行通信其流量必须经过本地网关出站,外部公网服务器回复的流量也必须经过本地网关入站才能路由到本地局域网的指定设备。
可以把网关理解为一栋“楼”的“楼长”,楼与楼之间的通信事务由网关进行管理,不能让楼中的“居民”直接插手楼间通信事务。
IP地址的分类
有类地址
早期,IP地址被划分为了五类地址,称作有类地址。如下表所示:
| 类别 | 首位 | 第一字节范围 | 默认掩码 | 用途 |
|---|---|---|---|---|
| A | 0 | 1 ~ 126 | /8 |
超大型网络 |
| B | 10 | 128 ~ 191 | /16 |
中型网络 |
| C | 110 | 192 ~ 223 | /24 |
小型网络 |
| D | 1110 | 224 ~ 239 | — | 组播 |
| E | 1111 | 240 ~ 255 | — | 保留/实验 |
比如我们家庭常见的192.168.1.2等等这类IP地址就属于C类地址,用于小型网络。一些网络例如10.124.12.10这类地址就属于A类大型网络。
但是目前这种分类已被废弃,原因是地址划分过于死板,不灵活。举个例子:假如南京某高校使用了A类地址,其网络地址为10.0.0.0,让我们算一下该网段拢共支持多少设备:
1 | |
看到了吗?一个网段能容纳1670万台设备,实际上远远用不到这么多。
这就说明旧式五类划分,要不就划分过大浪费;要不就划分过小不满足,例如C类地址一个网段才 2^8 - 2 = 254 台设备。
所以现代网络已抛弃有类划分,改用 CIDR。
CIDR (无类地址)
现代地址体系中,已不再按类进行IP地址的划分,取而代之的是CIDR无类地址机制。
无类地址:即用/n表示一个IP地址中的网络号的位数。也就是说我们可以将任何一个网络切分成一个子网络,按需进行切割。这个机制十分灵活,规避掉了按类型进行划分的弊端。
例如:
1 | |
/24表示该IP地址中,前24位是网络号,后8位是主机号,所以可以计算出该网段中可用主机地址共有2^8 - 2 = 254个,对应原来的C类地址。
再来看一个示例:
1 | |
该IP中,第一个字节8位与第二个字节的高4位为网络号(\12),剩下的20位为该网段中所有的主机号。
- 网络地址:
10.20.30.40 & 255.240.0.0 = 10.16.0.0。所以该网段起始地址为:10.16.0.0。 - 广播地址:主机号全1,即:
10.31.255.255(注:31是这么来的:0001 1111. 高四位是网络号,低四位主机号全1)。 - 可用主机地址范围:
10.16.0.1 ~ 10.31.255.254(去掉网络地址与广播地址)。 - 可用主机数目:
2^(32 - 12) - 2 = 2^20 - 2 = 1,048,574。
路由表爆炸与超网合并
当然, CIDR除了让地址划分更灵活之外,还解决了有类时代另一个致命问题——路由表爆炸,这是导致有类划分被彻底废弃的根因。路由器在转发数据包时,内部会维护一个路由表——这个表类似于“指路标”一样,指明该包数据下一跳该路由到哪个位置。
在有类地址时代中,每一类网段都要单独写一条路由。而当时C类网络是全球被使用最多的网络类型,1990s拢共有接近几十万个C类网段。这就意味着核心路由器面临路由表膨胀的问题——路由表的体积极具增大,内存不够、查表变慢、CPU 负载爆炸。如果不解决,互联网会在几年内瘫痪。
CIDR正是用于解决这个问题的。其解法是超网合并:若多个连续网段下一跳相同,就把它们合并为一个大网段一并路由。来看个例子:
某公司有16个网段,这16个网段都接在同一台边界路由器后面。对于外部核心路由器而言,去往这16个网段的下一跳完全相同。其网络拓扑如下:
1 | |
在旧式有类地址分类下来看,每个网段都要维护一条路由表,那么核心路由器为该公司就需要维护16个路由表条目。
但是在CIDR的视角下,我们会发现这些网络地址的前20位都是相同的,变化主要集中在20~23位。
1 | |
这时我们可以用/20来将这16条路由合并为1条。即:192.168.0.0/20。现在我们来验算下看看对不对:
1 | |
看到没有?合并前后地址范围逻辑完全是正确的。但是以前我们需要维护16个表项,现在只需1个表项就OK。整整缩小了16倍!这个效率是很高的。同时还有个隐藏福利:
合并之前,16个网段,每个网段2^8 - 2 = 254个可用地址。总的下来有254 * 16 = 4064个IP地址可用。
而CIDR合并之后,2^12 - 2 = 4094个可用地址。为什么会这样?因为合并之前每个网段都有个网络地址与广播地址被占用,拢共有16 * 2 = 32个地址被占用。而合并之后只被占用了2个,那么自然多了30个空余位置出来。
超网合并的优势是很明显的:
- 使得路由表地址缩小:多条路由压缩成一条,减轻核心路由器负担。
- 地址利用率提高:原来每个 /24 浪费 2 个地址,合并后只浪费整个大网段的2个。
- 互联网可扩展:全球路由表从几十万条降到几万条,互联网得以持续扩张。
Ps:CIDR超网合并的一个前提是地址连续,这是必要条件!还是上述公司的例子:如果地址不连续有空洞,即192.168.4.0该网段不属于该公司,那么在合并时不能直接合并为192.168.0.0/20,这么强行合并会把不属于自己的地址也圈进来,导致路由错误。这里尤其要注意。
IPv4私有地址
全球有三段公认的私有地址(也可以理解为局域网地址),这些地址在任何局域网段内部都是可以复用的。
| 类别 | 地址范围 | CIDR |
|---|---|---|
| A | 10.0.0.0 ~ 10.255.255.255 |
10.0.0.0/8 |
| B | 172.16.0.0 ~ 172.31.255.255 |
172.16.0.0/12 |
| C | 192.168.0.0 ~ 192.168.255.255 |
192.168.0.0/16 |
10.0.0.0/8一般用于大型网络(例如校园网等等)需要组建很多子网的场景。172.16.0.0/12设备数量介于家庭和企业之间,比如一些公司的分支机构。192.168.0.0/16基本是家庭路由器的默认配置,地址空间小,够用,且不容易和外部网络冲突。
关于使用规定,并没有强制。只要满足:使用三段地址之一;内网地址不冲突;流量出站时经过NAT网关 就行。
在家用网络里面你也完全可以给本地设备划分一个10.0.0.0/8,只是完全没有这个必要。
IPv4特殊地址
除了私有地址,IPv4还有一批有特殊用途、不能随便分配的地址。
- 0.0.0.0
这是本机任意地址的通配(IP_ADDR_ANY),根据不同的场景有不同的用法。
你比如DHCP请求时,此时本机还没有IP地址,因此使用0.0.0.0进行填充,等待IP分配;同时,当本机作为服务器进行客户端监听时,使用0.0.0.0:80表示监听本机80端口的所有连接。
- 127.0.0.0/8
本机本地环回地址。整个 127.0.0.0/8 都是回环地址,最常用的是 127.0.0.1(localhost)。
在这个地址下,数据包是发不出网卡的,会在内核內部兜一圈后重新发回给自己。只要协议栈正常,Ping127.0.0.1是一定能够通的。
环回地址只是在测试场景下使用,当移植协议栈之后可以尝试环回给自己发包,如果能正常接收说明协议栈出口和入口都是正常的。正常工况下不应该有设备被分配为环回地址。
- 255.255.255.255 / x.x.x.255(定向广播)
两个都是广播地址,用于向网段广播数据包的。
对于255.255.255.255:在DHCP发现服务与ARP广播中都有使用,其作用效果仅限本网段,不会被网关转发。也就是说向本网段内所有设备广播,但不能够跨越路由器。
x.x.x.255是定向广播,也是广播的一种,与255.255.255.255的核心区别在于:理论上网关可以转发该数据包,进而广播到别的网段。例如 我们处于网段:192.168.2.0/24,我们可以向另一个网段的广播地址192.168.1.255发包,该包数据经过网关后会进入192.168.1.0/24网段中并且广播给该网段中所有设备。
不过理论是理论,实际是实际。为了安全起见,现代路由器普遍禁止转发定向广播,因此在常规使用过程中,这两个广播地址的效果其实是等价的。
- 169.254.x.x/16 (链路本地地址)
这个地址用于在DHCP分配失败后的临时组网。当我们设备没能通过DHCP获取到地址时,就会从169.254.x.x/16中选出一个可用地址来分配给自己。此时设备只能和同网段其他 169.254.x.x 设备通信,上不了网。
举个例子:我们家庭网络地址为192.168.43.0/24。而某台设备在向路由器请求DHCP服务时失败,自己给自己分到了169.254.28.6,此时该设备和网段中的其它设备(192.168.43.x)是无法通信的,因为不处于同一个逻辑网段。此时若另一台设备也请求DHCP服务失败,同样给自己分配了一个169.254.28.3。此时,这两台设备处于同一网段,可以相互通信。
链路本地地址没有网关也上不了网,设备应定期重试DHCP服务,如果你发现你的设备IP地址一直为169.254.x.x,那么多半就是DHCP出问题了。
- 224.0.0.0/4 (组播地址)
用于一对多通信。例如视频直播:一个源向一组接收者发送,用组播地址。这里关于组播不展开。
IP 地址体系(IPv4)