在上一篇中,我们学习了传输层的 UDP 和 TCP 协议。但无论是 UDP 还是 TCP,最终都要交给网络层来寻找传输路径。网络层的核心协议就是 IP 协议。它负责为每一个数据包标注源地址和目的地址,并通过路由选择,把数据包一步步送到目标主机。本文就将带你深入理解 IP 协议的报文格式、IP 地址、NAT、网段划分与路由选择
一. IP协议
1. IP协议的报文格式

接下来,我们来讲解各个字段的含义及作用
1.1 4位版本
IP 协议 的版本分为 IPv4 和 IPv6 两个版本,其中,IPv4 是现在使用比较广泛的版本,而 IPv6 则是近几年的使用才多起来的,基于此,本文主要讲解 IPv4 这个版本。4位版本这个字段就记录了这个 IP 协议的版本
1.2 4位首部长度
由于 IP 数据报中的 选项 这一字段的存在,IP 数据报的报头的长度也是不固定的,而 4位首部长度 则记录下了 IP数据报报头的长度,单位是 “ 4个字节 ”。
1.3 8位服务类型
8位划分:前三位 优先权字段(已经弃用),紧接着四位 服务质量标志(TOS) 字段和最后一位保留字段(必须置为1)。四位服务质量标志(TOS) 字段分别为:最小延时、最大吞吐量、最高可靠性 和 最小成本,这四个字段相互排斥,只能选择一个
1.4 16位总长度(字节数)
16位总长度表示的是 一个 IP 数据报报头 + 载荷 的长度,最大为 64 kb。IP 协议中内置了拆包组包的功能,当一个比较大的 TCP 数据报交给 IP 协议进行封装时,IP 协议就会将这个 TCP 数据报 拆分成多个 IP 数据报 进行传输。而报文中的 16位标识 字段 就会标记那些 IP 数据报是同一个数据报拆分出来的,方便后续的组包操作
1.5 8位生存时间(TTL)
8位生存时间表示的是一个 IP 数据报 能够在网络上传输的最大时间,单位是 “ 次数 ”,IP 数据报每经过路由器转发一次,TTL 的值就 -1,当 TTL 减到 0 时,就说明这个数据报已经传输不到目的IP了,这个 IP 数据报就会被路由器丢弃
1.6 8位协议
8位协议标识的是传输层使用的是哪种协议,在目的主机 网络层收到 IP数据报 去分用时,会使用 IP 协议会解析 IP 数据报,拿到载荷并交给上层(传输层) 处理,这个 8位协议编号就决定了把数据交给哪一个传输层协议处理
1.7 16位首部检验和
和之前所说的校验和的作用一致,都是用来检测传输的数据是否出错的字段
1.8 32位源IP地址 和 32位目的IP地址
32 位源 IP 地址:发送该 IP 数据报的主机的 IP 地址
32 位目的 IP 地址:该 IP 数据报最终要送达的目标主机 IP 地址
IP地址是通过 32位的整数来表示的,但由于 32位的整数不方便阅读,通常会将 IP地址 写作 点分十进制 的形式,例如 192.168.100.98
32位的 IP 地址,最多只能表示大约 43亿 个不同的 IP,这个数量放到如今来看,是远远不够用的的,为了解决这个问题,IP 协议 引入了两个方案—— 动态分配IP地址 和 NAT 网络地址转换机制
2. 解决 IP地址不够用的两种方式
2.1 动态分配IP地址
动态分配 IP地址简单就是一个主机只有在上网时才会分配IP地址,下线后就回收该 IP地址,可以将该 IP地址重新分配给其他设备
这个方式属于治标不治本的方法,只能够暂时缓解,并不能从根源上解决问题
2.2 NAT 网络地址转换机制
NAT 的核心思想:多个内网主机共享同一个公网 IP 访问互联网
NAT 将所有的 IP 地址分为了两大类:公网IP(外网IP) 和 私网IP(内网IP),公网IP 是唯一的,而私网IP 在不同的局域网中是可以重复的,同一个局域网下的不同的网络设备有属于自己的私网IP,可以通过网络地址转换的方式使用同一个 公网IP 去访问互联网了
私网IP 转换为 公网IP 的示意图如下所示

像这样,同一个局域网下的 设备1,设备2,设备3 就可以在经过一个带有公网IP 的路由器后使用同一个 公网IP 去访问互联网了
NAT 背景下的不同的网络设备之间的网络通信
1. 同一个局域网下,设备A 访问 设备B
在同一个局域网下的 私网IP 是不能重复的,所以这两个设备的通信无需发生 IP 地址的转换,NAT不起作用
2. 公网设备A 访问 公网设备B
公网IP 本身也是不可以重复的,所以这两个设备的通信也是无需发生 IP 地址的转换的,NAT 不起作用
3. 不同局域网下的 设备A 访问 设备B
这个情况在 NAT 中是不被允许的 !
4. 公网设备A 访问 局域网下的设备B
这个情况在 NAT 中也是不被允许的 !
5. 局域网设备A 访问 公网设备B
这样的访问会触发 “ 网络地址映射 ”,具体流程如下图所示

此外,NAT 还会记录下一个网络地址映射表,这个表是路由器执行 网络地址映射 的依据,记录下了内网 " 私网 IP + 源端口 " 与公网 " 公网 IP + 分配的新的源端口 " 的一一对应关系,负责处理双向数据包的网络地址的转换 (避免在多台主机同时通过这个路由器发送 IP数据报时, IP 数据报 在返回的时候找不到对应的主机的情况)

2.3 使用 IPv6
IPv4使用 4 个字节作为 IP地址,而 IPv6 则是使用 16 个字节作为 IP地址,使用 IPv6 能表示的 IP地址 完全足够现在使用
3. 网段划分
一个 IP 地址会被分为两个网段,前半部分称为 “ 网络号 ”,后半部分称为 “ 主机号 ”
划分方式如下图所示

在同一个局域网中,网络号必须相同,主机号必须不同
在两个相邻的局域网中,网络号必须不同,主机号则无限制
当前网段划分的方式 —— 子网掩码
子网掩码是一个 32 位二进制数字(IPv4),配合 IP 地址使用,用来区分 IP 地址里 网络号 和 主机号
作用:
1.判断两台主机是否处于同一个子网(同一网段)
2.划分子网(把大网络切分成多个小局域网)
过去曾提出过一种将所有 IP 地址划分为 5类的划分 网络号 和 主机号 的方案(现已不再使用),如下图所示

特殊的 IP地址
1.将 IP 地址中的主机地址全部设置为 0,就成为了网络号,代表这个局域网
2.将 IP 地址中的主机地址全部设置为 1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包
3. 127.* 的 IP 地址用于本机环回(loop back)测试,通常是 127.0.0.1
4. 路由选择
定义:当 IP 数据包需要跨越多个网络传输时,主机、路由器根据 目的 IP 地址,决定数据包转发方向、下一跳设备的整套决策流程
网络环境是一个非常复杂的环境,任何一个路由器都无法存储所有的网络信息,但是每个路由器都可以知道附近的网络情况(知道谁与它相连)
当一个数据包到达某个路由器的时候,就会匹配这个路由器的 “ 路由表 ”,如果 目的IP 刚好匹配到了路由表中的记录,就直接按照当前对应的接口转发过去就可以了;如果没有匹配到,就会执行 “ 下一跳 ”,直接将该数据包转发给上一级路由器所在的位置
路由表的 5个核心字段
1.目的网络地址 / 前缀长度:目标网段(例:192.168.2.0/24)
2.下一跳地址:转发给上一级路由器的 IP;直连网络下一跳写直连
3.出接口:本机用来向外发送数据包的网卡接口
4.度量值(开销 Metric):多条可达路径时,用来选出最优路径
5.路由来源标记:直连路由 / 静态路由 / 动态路由
下一跳 转发流程示意图如下所示

下一跳 转发的服务器,越往上,所涵盖的范围也就越大,也就越有可能找到 目的IP 地址所对应的路由器
二. 以太网协议
接下来,我们接着来讲解 数据链路层 的 以太网协议
1.以太网数据帧的报文格式

1.1 目的地址 和 源地址
此处的 目的地址 和 源地址 指的不是 IP 地址,而是 mac 地址(物理地址)
mac 地址 的长度为 6个字节,固化在网卡(NIC)的 ROM 芯片里,出厂时由网卡厂商烧录,在出厂时就已经固定了
1.2 类型
标识以太网数据帧内部「数据载荷」里封装的是什么协议
有如图所示的 0800(IP数据报)、0806(ARP 地址解析协议) 和 8035(RARP 反向地址解析协议) 三种类型
ARP 不是传输业务层数据的协议,而是用来打辅助的协议,作用是 根据 IP 地址 来得到 对应的mac 地址
1.3 CRC 帧尾
记录的是 校验和,用来验证存储的数据是否发生改变
1.4 数据
记录的是存储的数据,也就是 载荷部分,最大为 1500 个字节,IP 数据报的 组包 和 拆包 操作更多的时候是因为数据链路层的限制才发生
2. DNS 域名解析系统
计算机通信依靠 IP 地址,但我们很难去记住一串数字,我们更擅长的是去记一个域名,当我们在浏览器中输入一个域名去搜索的时候,计算机就会自动的把这个域名解析成对应的 IP 地址
最初,DNS 是通过 hosts 文件 来实现 域名 到 IP地址 的映射的

用户每次在访问某个网站时,就会在 hosts 文件中搜索该域名对应的 IP地址,在通过 IP地址去真正地访问服务器
但是,hosts 文件的维护太复杂了,每当有新的网站诞生或销毁,都有对 hosts 文件进行更新,而在如今的时代,每时每刻都有数不清的网站在诞生和销毁,这也就造成了 hosts文件维护的巨大难度,所以现在已经不适用 hosts 文件 来完成映射了(hosts 文件 的功能仍然存在,优先级比 DNS 更高,主要的用途是用于程序测试)
为了解决 hosts 文件难维护的问题,DNS 就将 hosts 文件中的内容提取出来单独放到一个服务器上,这样的服务器就称为 DNS 服务器
用户每次在访问某个网站时,就要先去访问 DNS 服务器,把 要搜索的域名 对应的 IP地址拿到,并通过拿到的 IP地址 去真正地访问服务器
但是,这也就带来了新的问题,全球上网的设备有这么多,如果每次发起网络请求都需要先访问 DNS 服务器的话,那么 DNS 服务器就会承担 海量的并发量,那DNS服务器不就挂了吗?
为了解决这个问题,引入了以下两个解决方案
1. 缓存
你的电脑并不会在每次发送网络请求时都触发 DNS 请求,就比如你在第一次访问 www.sogou.com 进行了一次 DNS 之后,就会将该域名对应的 IP地址记录下来,下次再访问这个域名时,就不需要重新访问 DNS 服务器了
2. 设置多个 DNS 服务器
全球可以有多个 DNS 服务器,其中存储原始数据的 DNS 服务器称为 “ DNS 根服务器 ”,其他各种网络运营商就可以搭建 “ DNS 镜像服务器 ”
三. 小结
本文把 网络层 和 数据链路层 的核心内容串在了一起。IP 协议负责网络层的寻址与路由,通过源 IP 和目的 IP 为数据包指明方向,并借助 NAT、子网掩码和路由表完成跨网络转发。以太网协议负责数据链路层,用 MAC 地址在局域网内定位设备,通过以太网帧承载 IP 数据报,并依靠 ARP 完成 IP 到 MAC 的映射。DNS 则站在应用层,把人类易记的域名翻译成机器可读的 IP 地址,并通过缓存和分布式服务器体系扛住全球海量查询
一次完整的网络访问,其实就是这三者协作的结果:DNS 先解析出目标 IP,IP 负责把数据包路由到目标网络,以太网再在局域网内把帧送到目标主机。 分层不是割裂,而是各司其职、互相配合
到这里,我们从应用层出发,一路向下经过了传输层、网络层和数据链路层。希望这个系列能帮你建立起计算机网络的分层视角,再回头看 HTTP、TCP、IP 这些协议时,不再是零散的知识点,而是一张完整的网络通信地图
2242



被折叠的 条评论
为什么被折叠?



