文章目录
- 网络层
-
- [1. IP协议段格式](#1. IP协议段格式)
-
- [1.1 分片](#1.1 分片)
- [1.2 *为什么存在分片 / 分片是什么 ?*](#1.2 为什么存在分片 / 分片是什么 ?)
- [1.3 *如何理解 / 实现 分片与组装*](#1.3 如何理解 / 实现 分片与组装)
- [1.4 深入具体:分片 和 组装 的过程](#1.4 深入具体:分片 和 组装 的过程)
- [1.5 为什么不推荐 分片](#1.5 为什么不推荐 分片)
- [2. 网段划分](#2. 网段划分)
-
- [2.1 举例:国际间通信 && 国家内通信](#2.1 举例:国际间通信 && 国家内通信)
- [2.2 理解网段划分](#2.2 理解网段划分)
- [3. IP地址分类](#3. IP地址分类)
-
- [3.1 A~E类IP地址](#3.1 A~E类IP地址)
- [3.2 子网掩码](#3.2 子网掩码)
- [4. 私有IP地址 与 公有IP地址](#4. 私有IP地址 与 公有IP地址)
-
- [4.1 运营商](#4.1 运营商)
- [4.2 路由器的两套IP地址](#4.2 路由器的两套IP地址)
- [5. 路由](#5. 路由)
-
- [5.1 家用路由器 访问互联网资源](#5.1 家用路由器 访问互联网资源)
- [5.2 路由 的 "一跳"](#5.2 路由 的 “一跳”)
- [5.3 命令查看当前主机的路由表](#5.3 命令查看当前主机的路由表)
网络层
1. IP协议段格式
我们首先对上面I IP协议的协议段 的各种字段进行解释,部分字段会根据下文的情形进行进一步了解:
-
4位版本号(version) : 指定IP协议的版本, 对于IPv4就是4。
-
4位首部长度(header length) : 标识了 IPv4 头部的长度 ,以 4字节(32位) 为单位。该字段本身占 4 位,因此可以表示的长度范围是 0 到 15 * 32 位(即 0 ~ 60 字节), IPv4 头部的最小长度是 20 个字节。
-
8位服务类型(Type Of Service) :该字段可以分为3部分:
- 3位 优先级(Precedence) :用于指定数据包的优先级,表示数据包的重要程度或处理优先级。较高的数值表示较高的优先级。(现已弃用)
- 4位 TOS(Type of Service) 用于指定数据包的服务类型,分别表示:最小延迟、吞吐量、最高可靠性、最小成本,四者互相冲突,只能选一, 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要。
- MBZ(Must Be Zero) :保留字段 , 通常设置为零,用于保留将来可能使用的功能。
-
16位总长度(total length) : IP数据报整体占多少个字节
-
16位标识(id) :用于唯一标识 IP 数据包。
- 当 IP 数据包被分片传输时,所有分片属于同一个数据报的标识字段相同,(接收端就能够识别出它们属于同一个数据包)。
-
3 位标志字段 :控制和管理 IP 数据包的分片包括:
- DF(Don't Fragment) : 用于指示数据包是否可以被分片 。
- 如果 DF 标志被设置为 1 ,表示数据包不可分片,就算数据包的大小超过了网络链路的 MTU(最大传输单元)也不可分片。
- 如果 DF 标志被设置为 0 ,表示数据包可以分片传输。
- MF(More Fragments) : 更多分片标志 :用于指示是否还有后续的分片 。
- 当一个数据包被分片时,除了最后一个分片外,所有分片的 MF 标志都被设置为 1,表示还有后续的分片。
- 最后一个分片的 MF 标志被设置为 0,表示这是最后一个分片。
- 未使用的位(Reserved) : 保留位 ,目前未被使用,必须设置为 0。
- DF(Don't Fragment) : 用于指示数据包是否可以被分片 。
-
13位分片偏移(framegament offset) :用于指示分片后的当前数据包在原始数据包中的位置。
- 这个字段指定了数据包的数据部分相对于原始数据报的起始位置的偏移量,单位为8字节。这样接收端就可以将分片正确地组装成完整的原始数据报
-
8 位生存时间字段(Time to Live,TTL) 指定了数据包在网络中能够经过的最大路由器跳数(即路由器转发次数)。
- 每当数据包经过一个路由器时,TTL 字段的值就会减少 1,当 TTL 字段的值为 0 时,数据包将被丢弃并向原发送者发送一个 ICMP 超时消息
-
8位协议 : 表示上层协议的类型
-
16位头部校验和 : 使用CRC进行校验, 来鉴别头部是否损坏
-
选项字段(Options Field) 是一个可变长度的字段,最多可以包含 40 字节。选项字段通常用于提供一些额外的控制信息或功能扩展,但在实际使用中并不常见。(安全选项、时间戳选项、记录路由选项、宽松/严格源站选项 )
1.1 分片
上面关于IP协议段格式的介绍,对于下面的字段,我们提到了很多次所谓"分片",那么 何为分片?
下面我们解释分片的相关问题:
1.2 为什么存在分片 / 分片是什么 ?
先通过下图与文字,我们对分片首先有一个认识:
之后我们可以对分片进行一个简单的 总结 :
-
链路层由于物理特征的缘故,无法一次转发过大的数据 。每个链路层协议有其最大传输单元(MTU),在以太网中通常为1500字节。因此,一次转发的报文大小受到MTU的限制。
-
分片是在网络层(IP层)进行的 :当IP数据包大小超过某个链路或节点的最大传输单元(MTU)时,路由器或主机会将原始数据报进行分片,使其大小适合于网络上的传输。
-
分片后的数据包会带有相同的源和目的地址 ,但是会有不同的标识符以及分片偏移字段,以便接收方能够将分片正确地重组成原始的数据报。
1.3 如何理解 / 实现 分片与组装
此时我们知道了为什么会有分片,那么分片的是如何做到的?分片行为主要由下面三个字段完成:
上文我们已经对这三个字段进行了解释,这里再次简单提及:
- 16位标识 可以标记报文与报文之间的不同;
- 3位标识 有"更多分片位MF",可以标记一个报文是否被分片;
- 13位片偏移 指示分片后的数据包在原数据包的位置。
通过下面几点,我们可以更好的理解分片与组装,以及是如何实现的分片与组装:
- 分片行为不是主流
- 首先有一个正确的认识,在网络通信时,一般是尽量避免进行分片操作的
- 分片可能会导致复杂性增加、可靠性降低等安全风险(这个之后会谈)
- 如何识别报文间的不同
- 通过字段 "16位标识" :不同报文的标识不同,同一报文分片后的标识还是相同的
- 如何识别报文是否被分片
- 如果更多分片标志MF为1,是否一定被分片?
- 除了最后一个分片,其余分片的MF一定为1
- 对于最后一个分片,其 13位片偏移 一定不为0
- 得到结论, 对于一个报文,可以通过下面的方法判断是否被分片 :
- 更多分片标志为1 :分片
- 13位片偏移不为0 :分片
- 上面两条如果任意一条都无法满足,为独立报文
- (对于上面的结论,不能反着推,比如:分片的报文更多分片标志一定为1,通过下面一条我们可以完全对分片报文进行认识:)
- 如果更多分片标志MF为1,是否一定被分片?
- 通过这一点,在进行网络通信时,可以做到:当收到一批报文的时候,尽可能的先将分片的报文区分,并放到一起(方便传输)
- 如何找到一个分片的报文的位置?
- 根据上面的分析,我们得出结论:
- 首位报文 :更多分片标志 = 1,13位片偏移 = 0;
- 中间报文 :更多分片标志 = 1,13位片偏移 != 0;
- 尾部报文 :更多分片标志 = 0,13位片偏移 != 0;
- 如何保证分片全部接收?
-
这里先不考虑其他因素(ip报头),举一个简单的例子(更准确的例子在后文)
-
根据上图,只需要 根据分片包的偏移量进行升序排序,结合 "偏移量+自身大小=下一报文偏移量",扫描整个报文,如果有不匹配,则出现报文丢失,如果成功计算到结尾,证明接收完整 ,这一过程即 组装 !
-
- 之后有了这一过程,就可以根据接收信息(残缺或完整),指定组装方案
1.4 深入具体:分片 和 组装 的过程
我们知道: 数据包在分片之前,一定是一个独立的ip报文 :
那么,当数据包分片后,应该是 ①每个分片后的包应该是都带报头 ②不需要带报头,只要有第一个就行 ?------ 是①!
具体过程如下图所示:(该例是对上面不准确例子的扩充)
1.5 为什么不推荐 分片
我们知道: 在网络传输的过程中,分片是在网络层进行的,而上层不知道网络层是否发生了分片
并且:
- 分片增加了丢包概率,分片将本该一次发出的报文,变成了多个报文;
- 只有当所有分片的报文被全部收到时,此次传输才有意义(风险大)。
2. 网段划分
2.1 举例:国际间通信 && 国家内通信
我们首先看下面的一个例子, 模拟国际间的网络通信过程 :
通过上面的例子,主要理解一点: ip协议网络通信不是杂乱无章,而是划分好的 :上图模拟的是国际间的通信,同理在国家内,不同区域的通信也类似:
- 以我们国家举例,要通过二进制规划国内的省份,需要5个比特位:
同理根据这个思路,可以在全球范围将数据发送到 逐步缩小、精确的地区位置。
2.2 理解网段划分
有了上面的认识,我们进行网段划分的正题:
IP地址分为两个部分, 网络号和主机号 :
- 网络号 : 保证相互连接的两个网段具有不同的标识;
- 主机号 : 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号;
我们来看下图:
总结结论:
-
不同的子网实际就是把网络号相同的主机放到一起
-
如果 在子网中新增一台主机 , 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复(正如图中所写)
-
(就像学校中的学号等各种编号,前面的同专业同届一样的前缀号就像网络号,而主机号就是属于学生个人的编号)
所以有: 网络号可以表征不同的区域,在不同的查找过程中是不断变大且收敛的。
3. IP地址分类
3.1 A~E类IP地址
通过上面的内容,显然: 通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同。
同时,手动管理子网内的IP是很麻烦的事:
- 有一种技术叫做 DHCP ,可以 自动的给子网内新增主机节点分配IP地址 , 避免了手动管理IP的不便;
- 一般路由器都带有DHCP功能,因此路由器也可以看做一个DHCP服务器。
过去曾 提出一种 划分网络号和主机号的方案 , 把所有IP 地址分为五类, 如下图所示:
- A类 0.0.0.0 到 127.255.255.255
- B类 128.0.0.0 到 191.255.255.255
- C类 192.0.0.0 到 223.255.255.255
- D类 224.0.0.0 到 239.255.255.255
- E类 240.0.0.0 到 247.255.255.255
随着互联网发展,该划分方案的局限性很明显:
- 大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址
- 例如:申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机. A类地址的子网内的主机数更多.
- 然而实际网络架设中, 不存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了
3.2 子网掩码
由于有一定的缺陷,上面的划分方式现在已经不再进行 ,而针对这种情况,提出了新的划分方案: CIDR(Classless Interdomain Routing)
- 引入一个额外的 子网掩码(subnet mask) 来区分网络号和主机号 :
- 子网掩码也是一个32位的正整数. 通常用一串 "0" 来结尾;
- 将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
- 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;
通过给不同的路由器配置不同的子网掩码,可以看到不同的网络号:
- 目的IP & 当前路由器的子网掩码 = 该报文要去的目的网络
通过将目的 IP 地址与当前路由器的子网掩码进行逻辑与操作,可以确定目的 IP 地址所在的网络。逻辑与操作会将目的 IP地址中与子网掩码对应的网络部分留下来,而其他部分则被清零。这样就可以得到报文要去的目的网络。
如果目的 IP 地址是 192.168.1.50,当前路由器的子网掩码是 255.255.255.0,那么进行逻辑与操作后,得到的目的网络将是 192.168.1.0,这就是该报文要去的目的网络。
由于 路由器至少级联两个网络,每一个网络的网络号可能是不同的 , 每个路由器都要给直接连接的网络配置子网掩码。
4. 私有IP地址 与 公有IP地址
对于我们 个人主机的IP地址或者云服务器等的IP地址,其实都是 私有IP地址。
如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到互联网上,理论上可以使用任意的IP地址,但是 RFC 1918 规定了用于组建局域网的私有IP地址:
- 10.0.0.0 到 10.255.255.255,其中前8位是网络号,共有 16,777,216 个地址。
- 172.16.0.0 到 172.31.255.255,其中前12位是网络号,共有 1,048,576 个地址。
- 192.168.0.0 到 192.168.255.255,其中前16位是网络号,共有 65,536 个地址。
包含在这个范围中的, 都称为私有IP, 其余的则称为全局IP(或公网IP);
4.1 运营商
为什么路由器有两套IP地址?我们思考一下下面的问题:
-
如果一家想上网,应该有哪些过程?
- 有运营商在该区域有网络覆盖
- 该家庭联系运营商进行光纤入户
- 工作人员上门调解解调器(猫)、无线路由器
- 开户、账号密码、配置路由器的账号密码、运营商认证密码
- 配置路由器 - 设置wifi名称+密码
- 此时可以上网
-
为什么我们平时在各种平台上获取服务,却要将话费给运营商?
- 基础设施是运营商铺设的
-
为什么国内无法访问部分国外网站?
- 不管是个人的手机还是路由器,都是有账号认证的
- 运营商可以判断我们的地址、信息,并加以限制
-
为什么手机欠费了,依然可以拨通运营商电话或者急救电话等?
- 和之前一样,手机/路由器是有账号认证的,运营商可以查询你的账户余额并进行限制
4.2 路由器的两套IP地址
现在来看下图:
从上图,我们首先知道:路由器天然的会构建子网(即局域网)
对于 家用路由器:
- 对内:面对自己构建的子网
- 对外:自己本身也是别的路由器构建子网的一个主机
因此,路由器一定要有两套地址:
- 对内:LAN口IP(即局域网IP)
- 对外:WAN口IP,自己所在上级子网给自己分配的IP
有了路由器两种IP的概念,我们此时看下文,我们对图中内容进行简单总结:
- 路由器 LAN口连接的主机,都从属于当前这个路由器的子网中;
- 不同的路由器, 子网IP其实是一样的(通常都是192.168.1.1). 子网内的主机IP地址不能重复. 但是子网之间的IP地址是可以重复的;
- 每一个家用路由器, 又作为运营商路由器的子网中的一个节点. 这样的运营商路由器可能会有很多级,最外层的运营商路由器, WAN口IP就是一个公网IP了;
- 子网内的主机和外网进行通信时, 路由器会将IP首部中的IP地址进行替换(替换成WAN口IP),通过逐级替换,最终数据包中的IP地址成为一个公网IP. 这种技术称为 NAT(Network Address Translation,网络地址转换)。
- 如果希望自己编写的服务器程序能够在公网上被访问到, 就需要把程序部署在一台具有外网IP的服务器上(云服务商购买)
5. 路由
5.1 家用路由器 访问互联网资源
如果要从某个家用网络访问运营商的相关内容,具体过程是什么样的?
(比如在家连wifi访问视频平台刷视频)。
下面为一次 从家用路由器访问互联网资源的过程:
-
内部设备请求:
- 当一个内部设备(比如一台电脑或手机)想要访问互联网上的资源时,它会 向家用路由器发送请求。
-
家用路由器转换:
- 家用路由器接收到这个请求, 会将请求中的源 IP 地址和端口号修改为路由器的公共 IP 地址和一个新的端口号。为了确保互联网上的服务器将响应发送回正确的地址和端口。
-
请求发送到运营商路由器:
- 修改后的请求被发送到家用路由器的互联网连接,经过家庭网络中的调制解调器(如果有)后,最终 抵达运营商的路由器 。
-
运营商路由器转发:
- 运营商路由器接收到请求后 ,会 根据目标 IP 地址将请求转发到互联网上的目标服务器 。
-
服务器响应:
- 目标服务器收到请求后 ,会生成响应, 并将其发送回运营商的路由器 。
-
响应返回家用路由器:
- 运营商路由器接收到响应后,将其发送回到家用路由器 ,根据之前的转换表将响应的目标 IP 地址和端口号转换回原始的内部设备的私有 IP 地址和端口号。
-
内部设备接收响应:
- 家用路由器将响应发送到请求的内部设备 ,完成数据传输过程。
正如前面提到的,这个过程中,NAT 起了关键作用:
- 允许家庭网络中的多个设备共享一个公共 IP 地址,并提供了一定程度的网络安全性。
5.2 路由 的 "一跳"
路由的过程 , 就是这样执行如下图一跳一跳(Hop by Hop)的 "问路" 过程:
- 数据链路层负责实现局域网内部的数据传输,它通过使用MAC地址来标识和定位设备,并在相邻节点之间传输数据帧。这种通信是一跳一跳地进行的,每一跳都是从一个网络节点到另一个网络节点的数据传输。
IP数据包的传输过程就像问路:
- 当IP数据包,到达路由器时,路由器会先查看目的IP;
- 路由器决定这个数据包是直接发送给目标主机, 还是需要发送给下一个路由器;
- 反复进行, 直到到达目标IP地址;
那么如何判定当前这个数据包该发送到哪里呢?
- 每个节点内部维护一个路由表;
- 路由表存储了网络中各个目的地址的信息以及如何到达这些地址的路由信息。
5.3 命令查看当前主机的路由表
我们可以通过route
命令查询当前的路由表情况(下面为linux环境的云服务器):
cpp
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 203.0.113.1 0.0.0.0 UG 0 0 0 eth0
link-local 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
下面我们对每个字段进行解释:
- Destination :目标网络地址或主机地址。即路由指向的目标。
- GateWay :下一跳的 IP 地址,即将数据包转发到达目标的下一个路由器或网关。
- Genmask :网络地址的子网掩码。它用于确定网络地址的范围。
- Flags :与路由相关的标志 ,常见的标志包括:
- U :表示路由可用(up)。
- G :表示该路由条目指定了一个网关。
- H :表示该路由条目指定了一个主机(host)。
- Metric :指定到达目标的跃点数(hops)或其他成本度量。
- Ref :引用计数,表示该路由条目被引用的次数。
- Use :该路由条目被使用的次数。
- Iface :数据包应该从哪个网络接口发送出去,以便到达目标。
随后基于整个路由表:
- 第一行表示默认路由,即所有未知目标都将通过网关 (
gateway
) 转发出去。 - 第二行表示本地链路(link-local),对于同一子网内的通信。
- 第三行表示一个特定目标网络
172.22.96.0/20
的路由,没有指定网关,表明这个网络是直接可达的,数据包可以直接发送到该网络。
用该命令可以获取:系统如何将数据包从源发送到目标,以及经过哪些路由器或网关。