42.网络层IP协议
文章目录
问题引出
网络通信中主机之间不是直接连接的,数据需要通过多个路由器转发。主机发送数据时不关心具体内容,只需要将报文转发到下一个路由器。每个路由器根据某种规则决定将报文转发到哪个下一跳路由器。这种转发过程会一直持续,直到报文到达目的主机。TCP层只关心端到端的通信,而IP层负责处理报文在网络中的实际转发路径。发送主机将数据交给第一个路由器后,后续的转发过程对发送主机是透明的。
以下图为例:

主机b需要将数据传输给主机c,这一过程涉及多个路由器的转发,包括路由器f、g、h等。主机b为何选择将数据交给路由器f而非本地回环是一个关键问题。网络通信中的路径选择问题本质上是确定数据从源主机到目标主机的传输路径。简而言之,数据在网络层传输聚焦于两个问题:为什么要交给下一个路由器(路径选择)?如何将数据交给下一个路由器?
- 路径选择问题由网络层决定,具体由IP协议处理。在网络通信中,每个主机和路由器都需要具有唯一性的IP地址,特别是公网IP地址,以确保全球范围内的唯一性。IP地址分为子网IP和内网IP,以及公网IP。公网IP具有全球唯一性,例如云服务器的IP地址可以在任何地方访问。主机b在进行路径选择时,主机c的IP地址是一个重要依据。(这是这篇博客的重点)
- 数据如何在相邻设备之间传输,则属于局域网通信问题。整个网络通信可以看作是由无数个局域网通信共同构成的广域网通信。局域网通信涉及数据链路层,包括MAC地址和碰撞检测等技术(有关数据链路层的问题在下一小节解释)。网络层和数据链路层各自解决不同的问题,网络层关注路径选择,数据链路层关注相邻设备间的数据传输。
IP协议与传输层
在网络基础部分我们已经提到过,下面相当于是对之前学习的复习
网络分层包括应用层、传输层、网络层和链路层,每层添加自己的报头并解决特定问题。
- 应用层报头确保报文完整性和序列化支持;
- 传输层(TCP/UDP)处理流量控制、拥塞控制和超时重传;
- 网络层(IP)专注于路由选择和跨网络数据包转发;
- 链路层负责数据帧传输。
IP协议的核心作用是将数据包从源主机跨网络传输到目标主机,但不保证可靠性(如丢包处理)。传输层将数据分段(segment)交给网络层,网络层将其封装为数据报(datagram),链路层则形成数据帧(frame)。IP层转发过程中,路由器等网络设备被视为"节点",它们根据目标IP地址进行路由决策。主机虽然也参与路由控制,但功能较弱,主要区分本地和跨网络转发。IP协议的关键在于提供跨网络传输能力,而可靠性保障由上层协议实现
TCP与IP的关系
在网络传输中,TCP/IP协议栈的目标就是为操作系统和用户提供可靠的数据传输能力。
- TCP主要负责策略层面的问题,包括流量控制、拥塞控制、超时重传、确认应答等机制,而IP层则负责具体的报文转发工作。这两层协议协同工作,共同确保数据能够可靠地从源主机传输到目的主机。
- TCP的策略机制最终都会转化为IP层的报文,这些报文中会包含网络层和传输层的报头信息。TCP的可靠性策略本质上是在做决策,就像人们日常生活中需要做决策和执行一样,比如决定是否上课或选择吃什么食物。
IP地址的结构
IP地址分为IPv4和IPv6两类,IPv4是目前公网主流使用的协议,而IPv6在我国部分大机房和内网建设中已有较多应用,但在国际上尚未广泛使用。IPv4地址采用点分十进制表示法,形式为四个0到255的数字,如192.168.1.1。这种表示法在网络套接字编程中常见。IP地址用于唯一标识主机,在公网中,每个主机和路由器都需要有自己的IP地址。
IP地址的两部分构成:目标网络和目标主机。目标网络用于在大范围路径选择中确定方向,而目标主机用于在局部范围内精确定位。IP地址采用点分十进制表示法,分为四部分,但逻辑上由目标网络和目标主机两部分组成,这与子网划分有关。在网络数据包转发过程中,路由器首先根据目标网络选择路径,逐步接近目标网络后,再根据目标主机进行最终定位。
IP协议报头结构

- 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4.
- 4位头部⻓度(header length): IP头部的⻓度是多少个32bit, 也就是 length 4 的字节数. 4bit表⽰最⼤的数字是15, 因此IP头部最⼤⻓度是60字节
- 8位服务类型(Type Of Service): 3位优先权字段(已经弃⽤), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表⽰: 最⼩延时, 最⼤吞吐量, 最⾼可靠性, 最⼩成本. 这四者相互冲突, 只能选择⼀个. 对于ssh/telnet这样的应⽤程序, 最⼩延时⽐较重要; 对于ftp这样的程序, 最⼤吞吐量⽐较重要
- 16位总⻓度(total length): IP数据报整体占多少个字节
- 16位标识(id): 唯⼀的标识主机发送的报⽂. 如果IP报⽂在数据链路层被分⽚了, 那么每⼀个⽚⾥⾯的这个id都是相同的
- 3位标志字段: 第⼀位保留(保留的意思是现在不⽤, 但是还没想好说不定以后要⽤到). 第⼆位置为1表⽰禁⽌分⽚, 这时候如果报⽂⻓度超过MTU, IP模块就会丢弃报⽂. 第三位表⽰"更多分⽚", 如果分⽚了的话, 最后⼀个分⽚置为0, 其他是1. 类似于⼀个结束标记
- 13位分⽚偏移(framegament offset): 是分⽚相对于原始IP报⽂开始处的偏移. 其实就是在表⽰当前分⽚在原报⽂中处在哪个位置. 实际偏移的字节数是这个值 8 得到的. 因此, 除了最后⼀个报⽂之外, 其他报⽂的⻓度必须是8的整数倍(否则报⽂就不连续了).
- 8位⽣存时间(Time To Live, TTL): 数据报到达⽬的地的最⼤报⽂跳数. ⼀般是64. 每次经过⼀个路由, TTL -= 1, ⼀直减到0还没到达, 那么就丢弃了. 这个字段主要是⽤来防⽌出现路由循环
- 8位协议: 表⽰上层协议的类型
- 16位头部校验和: 使⽤CRC进⾏校验, 来鉴别头部是否损坏
- 32位源地址和32位⽬标地址: 表⽰发送端和接收端
- 选项字段(不定⻓, 最多40字节): 略
IP层的报头结构与TCP报头类似,标准长度都是20字节。IP报头比TCP报头简单,因为它主要关注路由功能,而不涉及复杂的策略控制。IP报头中最关键的字段是目的IP地址。理解IP报头需要回答两个核心问题:一是IP报头如何进行解包和封包,二是IP报文如何进行分用。
- 解包:IP报文的解包过程涉及识别前20个字节的标准报头,以及可能的选项部分。IP报头包含一个4位首部长度字段,其取值范围为0到15,但由于基本单位是4字节,实际报头长度范围是0到60字节。标准IP报头必须包含20字节,因此实际长度范围是20到60字节,支持最多40字节的选项。如果没有选项,首部长度字段应填写5(0101二进制),因为5×4=20字节。通过首部长度和16位总长度字段,IP层可以精确计算出报头和有效载荷的边界。
- 分用:IP报头中的8位协议字段表示上层协议的类型,从而将解包后的字段交给对应协议实现分用。
网段划分(重点)
理解IP的关键在于理解网段划分,这与TCP的理解类似,TCP的理解在于其周边策略,而IP的理解在于网络划分。网段划分的本质是对网络进行人为设置,以便未来可以通过目的网络和子网划分策略将报文转发出去。这种设计不仅包括子网划分,还包括路由器的路由算法,涉及软件和硬件层面的结合。
网络的设计者通常是网络服务提供商(ISP),在中国主要是三大运营商:移动、电信和联通。这些运营商负责网络基础设施建设,类似于国家修建道路。网络被设计好后,才能支持报文从源主机到目标主机的传输。子网划分的宏观设计方案是人为设置网络,使得报文可以通过目的网络和子网划分策略进行转发。网络的设计还包括路由器的路由算法,这些算法在软件层面运行,而子网划分则偏向硬件层面,两者结合构建完整的网络设施。
IP地址包含两个部分:网络号和主机号
- 网络号:保证相互连接的两个⽹段具有不同的标识
- 主机号:同⼀⽹段内, 主机之间具有相同的⽹络号, 但是必须有不同的主机号
子网掩码
直到现在还有一个问题还没得到解决:在一个IP地址中,哪几位表示网络号,哪几位表示主机号呢?
- 过去曾经提出⼀种划分⽹络号和主机号的⽅案, 把所有IP 地址分为五类, 如下图所⽰(该图出 ⾃[TCPIP])

随着Internet的⻜速发展,这种划分⽅案的局限性很快显现出来,⼤多数组织都申请B类⽹络地址, 导致B类地址很快就分配完了, ⽽A类却浪费了⼤量地址
- 针对这种情况提出了新的划分⽅案, 称为CIDR(Classless Interdomain Routing)(⽆类别域间路由)
- 引⼊⼀个额外的⼦⽹掩码(subnet mask)来区分⽹络号和主机号;
- ⼦⽹掩码也是⼀个32位的正整数. 通常⽤⼀串 "0" 来结尾;
- 将IP地址和⼦⽹掩码进⾏ "按位与" 操作, 得到的结果就是⽹络号;
- ⽹络号和主机号的划分与这个IP地址是A类、B类还是C类⽆关;
- IP地址和⼦⽹掩码还有⼀种更简洁的表⽰⽅法,例如140.252.20.68/24,表⽰IP地址为140.252.20.68, ⼦⽹掩码的⾼24位是1,也就是255.255.255.0

有了子网掩码这个工具,我们可以使用它将IP地址按照需要来划分网络号与主机号。运营商在IP地址分配和网络建设中起着核心作用,他们负责将全球IP地址资源分配给各个地区和机构。在实际网络划分中,需要确保相互连接的子网具有不同的网络标识,就像学校中每个学院都有唯一的院号一样。同时,在同一个子网内部,所有主机必须具有相同的网络号但不同的主机号。运营商还需要管理路由表,确保数据能够正确地从一个网络转发到另一个网络。
网段划分与数据传递
主机需要将数据传递给另一台主机,但主机本身无法进行自我决策。主机通过目标IP地址的网络号来确定目标网络。
-
如果相同则确定目标网络属于同一子网,进行局域网通信,包括封装MAC帧、碰撞检测和避免碰撞。
-
如果网络号不同,主机无法确定报文应该发送给谁,但知道报文不属于当前子网,因此默认将报文交给路由器进行转发。
通过这种方式,可以实现两个子网之间的通信。IP地址的转发分为两个阶段:第一阶段只看目的网络,将报文转发到目标网络;第二阶段在目标网络内进行内网转发。
子网划分的本质就是通过层级结构将查找过程从线性遍历变为可以批量淘汰非目标群体的过程,这与二分查找的原理类似,都是通过减少需要比较的对象数量来提高效率。
路由器在子网划分中的作用
子网内的主机IP地址由路由器分配,路由器具有构建子网的能力。当设备连接路由器时,路由器会为其分配一个唯一的IP地址。路由器在构建子网时,会给自己分配一个固定的网络号和主机号(通常是1)子网内的主机通过路由器分配的IP地址进行通信,路由器负责管理子网内的IP地址分配和报文转发。
当新主机接入网络时,路由器会通过DHCP服务为其分配一个可用的IP地址,这个过程是动态完成的,不需要手动配置。DHCP工作在应用层,它不仅可以分配IP地址,还可以提供子网掩码、默认网关和DNS服务器等信息。路由器通过DHCP管理的IP地址通常是私有地址,只能在本地网络中使用,这与公有IP地址(如云服务器的IP地址)不同。DHCP简化了网络管理,特别是在大型网络中,可以避免IP地址冲突并实现地址的重复利用。当主机离开网络时,其IP地址可以被回收并分配给其他主机。
特殊的IP地址
将IP地址中的主机地址全部设为0, 就成为了⽹络号, 代表这个局域⽹;
将IP地址中的主机地址全部设为1, 就成为了⼴播地址, ⽤于给同⼀个链路中相互连接的所有主机发送数据包;
127.*的IP地址⽤于本机环回(loop back)测试,通常是127.0.0.1。发送数据给环回地址时,报文在内核协议栈中走一圈,不走链路层,只做本地环回测试。
IP地址的数量限制
我们知道, IP地址(IPv4)是⼀个4字节32位的正整数. 那么⼀共只有 2的32次⽅ 个IP地址, ⼤概是43亿左右. ⽽TCP/IP协议规定, 每个主机都需要有⼀个IP地址。这意味着, ⼀共只有43亿台主机能接⼊⽹络么?
实际上, 由于⼀些特殊的IP地址的存在, 数量远不⾜43亿; 另外IP地址并⾮是按照主机台数来配置的, ⽽是每⼀个⽹卡都需要配置⼀个或多个IP地址。CIDR在⼀定程度上缓解了IP地址不够⽤的问题(提⾼了利⽤率, 减少了浪费, 但是IP地址的绝对上限并没有增加), 仍然不是很够⽤. 这时候有三种⽅式来解决
- 动态分配IP地址: 只给接⼊⽹络的设备分配IP地址. 因此同⼀个MAC地址的设备, 每次接⼊互联⽹中, 得到的IP地址不⼀定是相同的
- NAT技术(后⾯会重点介绍)
- IPv6: IPv6并不是IPv4的简单升级版. 这是互不相⼲的两个协议, 彼此并不兼容; IPv6⽤16字节128位来表⽰⼀个IP地址; 但是⽬前IPv6还没有普及
私有IP地址和公网IP地址
全球IP地址资源被划分为公网IP和私有IP两部分,公网IP由各国、组织和高校申请使用,申请过程复杂,中国可能获得不同类别的网络地址段。私有IP地址包括10开头、172.16到172.31、192.168开头,只能用于局域网。公有IP地址全网唯一。不同规模的组织选择不同的私有IP地址搭建网络。私有IP地址可能出现重复,公有IP地址不能重复。
IP地址众多,任何组织在搭建网络时都使用私有IP来构建内网。家庭用户通常通过购买路由器来组建局域网,因为路由器具有构建子网的能力。⼀个路由器可以配置两个IP地址, ⼀个是WAN⼝IP, ⼀个是LAN⼝IP(⼦⽹IP)。
- 路由器LAN⼝连接的主机, 都从属于当前这个路由器的⼦⽹中。不同的路由器,⼦⽹IP其实都是⼀样的, ⼦⽹内的主机IP地址不能重复. 但是⼦⽹之间的IP地址就可以重复了.
- 每⼀个家⽤路由器, 其实⼜作为运营商路由器的⼦⽹中的⼀个节点. 这样的运营商路由器可能会有很多级, 最外层的运营商路由器, WAN⼝IP就是⼀个公⽹IP了
- ⼦⽹内的主机需要和外⽹进⾏通信时, 路由器将IP⾸部中的IP地址进⾏替换(替换成WAN⼝IP), 这样逐级替换, 最终数据包中的IP地址成为⼀个公⽹IP. 这种技术称为NAT(Network Address Translation,⽹络地址转换)

路由的过程
已经了解到了网络的基本框架,接下来我们讨论数据是如何在网络中转发的,而在复杂的⽹络结构中, 找出⼀条通往终点的路线就是路由。

路由的过程, 就是这样⼀跳⼀跳(Hop by Hop) "问路" 的过程。所谓 "⼀跳" 就是数据链路层中的⼀个区间. 具体在以太⽹中指从源MAC地址到⽬的MAC地址之间的帧传输区间。当IP数据包, 到达路由器时, 路由器会先查看⽬的IP,路由器决定这个数据包是能直接发送给⽬标主机, 还是需要发送给下⼀个路由器,依次反复, ⼀直到达⽬标IP地址。
路由表
那么路由器如何知道一个数据帧要发送到哪里呢?这就需要路由器在内部维护一张路由表,通过查找路由表来判断数据帧发送到哪里去。
- 路由表可以使⽤route命令查看
- 如果⽬的IP命中了路由表, 就直接转发即可
- 路由表中的最后⼀⾏,主要由下⼀跳地址和发送接⼝两部分组成,当⽬的地址与路由表中其它⾏都不匹配时,就按缺省路由条⽬规定的接⼝发送到下⼀跳地址
当报文到达时,网络层会提取目的IP地址,并遍历路由表,依次用子网掩码与目的IP进行按位与运算,再与目标网络对比。如果匹配成功,报文将通过对应的网络接口(i face)转发到指定网络。如果遍历所有条目均未匹配,则使用缺省路由(子网掩码0.0.0.0),直接将报文通过默认接口转发出去。
- 例如,当目的IP地址为
192.168.56.3时,路由器会将其与子网掩码255.255.255.0进行按位与运算,得到网络号192.168.56.0,再与路由表中的Destination字段对比。若匹配成功,报文将通过对应的Iface接口转发。 - 另一个例子是目的IP为
202.10.1.1,这是一个公网IP。路由器会依次对比子网掩码和目标网络,若均不匹配,则使用缺省路由,通过eth0接口将报文转发到默认网关192.168.10.1。
shell
user@iZ7xvdsb1wn2io90klvtwlZ:~$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 100 0 0 eth0
100.100.2.136 _gateway 255.255.255.255 UGH 100 0 0 eth0
100.100.2.138 _gateway 255.255.255.255 UGH 100 0 0 eth0
172.18.0.0 0.0.0.0 255.255.192.0 U 100 0 0 eth0
_gateway 0.0.0.0 255.255.255.255 UH 100 0 0 eth0
IP分片机制
IP报文如果过长,会在底层进行分片处理。数据链路层规定单次发送的数据帧有效载荷不能超过MTU(最大传输单元,通常为1500字节),这直接影响网络层IP报文是否需要分片。IP报头中包含标志位、标识符和片偏移字段用于分片和重组。分片会增加丢包风险,因为任何一片丢失都会导致整个报文无法重组,传输层会将其视为丢包并进行重传。分片数量越多,整体丢包概率越高,因为需要所有分片都成功到达才能完成重组。
TCP滑动窗口与IP分片机制的关系
传输层TCP协议使用滑动窗口机制控制数据发送量,其大小受拥塞窗口和接收方能力限制。一个核心问题是为什么TCP不将多个小报文合并成一个大报文发送,而是分成多个数据段传输。IP层存在报文分片机制,当IP报文长度超过数据链路层MTU限制时,网络层会自动进行分片处理。
数据链路层的MTU限制(通常1500字节)是导致IP分片的直接原因,这类似于快递公司对单个包裹重量的限制。IP分片和重组的工作必须由网络层自己完成,就像寄送电脑时需要用户自己拆分成符合重量限制的小包裹一样。IP报头中专门设计了三个字段(标志位、标识符和片偏移)来支持分片和重组功能。分片会增加网络传输的复杂性,任何一片丢失都会导致整个报文无法重组,被传输层视为丢包。为了避免在网络层IP分片,在传输层TCP就不能发送大报文。