网络层的协议-IP协议簇

互联网层-IP协议簇

上一节聊完了数据链路层,我们知道,两台计算机如果需要进行通讯的话,就需要先知道彼此的 MAC地址,然后将数据封装成 以太网帧 进行传输。但是我们的野心并没有止于此,因为需要更多的计算机参与网络(这个数量是+∞),那总不能把所有计算机的 MAC地址 在每一台上面都存储一份吧,即使这样,物理介质的互通也不现实。所以还能怎么办,那就包多一层嘛。

所以,IP协议 这一层又应运而生。

那么我们可以重新看一下分层模型:

与七层模型的匹配(via《图解TCP/IP》)

他主要位于互联网层,那他在这一层主要解决的问题就是数据的走向问题,也仅仅是走向的问题,不会对数据进行纠错,也不会负责重发的动作(即使数据丢失的话)。而这些问题会在再上一层的 传输层 进行补充解决。

简单的描述

那就从传输层开始,假设我们现在的应用使用的是 TCP协议,那么 TCP数据包 将会传递给 IP协议(互联网层),但是数据链路层是需要知道彼此的 MAC地址 的,不过目前我没有那个地址。所以就需要一个东西来辅助了:路由控制。每一个主机上(包括电脑、手机、路由器等等)都会内置一个路由控制表,他会指明所需要请求的 IP 应该通向哪一台 路由器 或者在最后一级的时候通向哪台提供服务的 计算机,所以我们的主机下一步需要在数据链路上填上相连接的 路由器MAC地址

这个过程就很像我们日常使用的快递服务了,众所周知(当然我也不知道你们知不知),快递公司是有省级转运仓,市级转运仓,还有各区县镇转运仓的,这些转运仓我们可以比作 路由器,我们将快递交给快递员的时候,当然快递员不知道怎么走而且他也只负责他区域内部的事情而已,所以他交给 镇转运仓转运仓 就比较忙了,他需要根据快递包裹上的地址省市区(IP地址 的分段管理)再分拨给其他转运仓,比方说是市内的,就直接转给其他的 各区县镇转运仓,然后他们需要依据后面的详细地址,将快递派出去;而如果是省外的,就需要 省转运仓 去分拨,那么自然的会将包裹往 省转运仓 转运。

所以一个快递的运输上,省市区地址是用来 分区 的,详细地址是最后用来定位具体位置的,整个过程跟 IP数据包 的走向有异曲同工之妙。

那么这中间就涉及 IP地址路由控制路由监控 等内容了。

IP地址要点

IP地址的定义

那么我们在公司经常会有路由器进行 IP自动获取,获取到这个 IP 呢,大概就是这个样子:192.168.1.7

下面关于 二进制十进制 的转换,请灵活使用系统自带的 计算器 进行计算:

MacOS自带的计算器

当然,我们用的是 十进制 的表示方法,其实 IP 在网络中传输是要求 二进制 的,也就是类似于这样子:

1
1100 0000 1010 1000 0000 0001 0000 0111

上面表示的 IP 翻译成 十进制 的话,刚好是 192.168.1.7

但是我们讨论的时候需要基于 二进制 的,IP 规定总长度是 32二进制 数(如上面我的 IP地址

IP地址组成部分

IP地址 从左往右,由 网络标识主机地址 两个部分进行组成。我们知道,路由器是可以将网络中的计算机进行网络分段的,以便应用程序利用 网络分段 进行数据的传输。如果网络中有多个路由器的话,也可以通过 网络标识 进行数据的分类传输。可以通过斜杆 / 记录前几位表示网络标识,例如:192.168.1.7/24 表示前 24 位(二进制位)标记网络标识,而剩余的其他位数标记 主机地址

当然,现在大部分的做法是使用 子网掩码 来做分割,但是 IP地址分割法 的做法依然会存在某些小型企业中。

IP地址分类

简单记一下即可,不用强记。

A类地址:首位 0 开始,前 8 位(包括强制性 0 的那一位)表示网络标识,后 24 位表示主机地址,可以容纳 16777214 个主机;

B类地址:首位 10 开始,前 16 位(包括强制性 10 的那两位)表示网络标识,后 16 位表示主机地址,可以容纳 65534 个主机;

C类地址:首位 110 开始,前 24 位(包括强制性 110 的那三位)表示网络标识,后 8 位表示主机地址,可以容纳 254 个主机;

D类地址:首位 1110 开始, 32 位(包括强制性 1110 的那四位)表示网络标识,没有主机标识,常用语 多播

éi,为啥都少 两台主机(比方说 A类地址,有 24 位表示主机,应该是 16777216 台主机才对,那是因为主机地址不可以包含全部为 1 或者 0 的情况,所以基本都会淘汰掉 2 台主机的 IP地址

子网掩码

虽然经过上面对 组成结构分类 的讨论,但是 IP地址 还是枯竭了,不够所有全人类的计算机使用,而 分类 也只是简单的按照 8 位,16 位,24 位 进行划分,所以这时候需要一个更加灵活的划分方式,以便于制造更多的 IP地址 出来供计算机使用。

子网掩码长度也是 32 位,每一位与 IP地址 相对应,连续的 1 表示连续的几位 IP 均为网络表示,连续的 0 则表示主机的位置,来看看这个:

IP和子网掩码

1
2
3
4
5
IP地址:192.168.1.14
子网掩码:255.255.255.0
---- 二进制法 ----
1100 0000 1010 1000 0000 0001 0000 1110 <-- IP地址
1111 1111 1111 1111 1111 1111 0000 0000 <-- 子网掩码

此时表示的是前 24 位为网络标识,那我们转换一下思路,要表示 26 位怎么办,此时状态如下:

1
2
1111 1111 1111 1111 1111 1111 1100 0000 <-- 子网掩码二进制
255.255.255.192 <-- 子网掩码十进制

所以子网掩码的基本思路就是,通过二进制的来标记随便的几位作为网络标识,以便可以拓展 IP地址 的分类,灵活放缩可以容纳主机的 IP 地址个数。而目前基本是使用这种方式来对网络中的计算机进行分段。

IP广播和多播

广播,即对一个网络端内的所有主机都发送同一个数据包。对同一个网段内的主机发送广播称为 本地广播,而需要跨网段的广播称为 直接广播

本地广播只要对诸如 192.168.1.255/24 发送数据即可将数据发送到网段为 192.168.1 的所有主机。

而直接广播比如本机地址 192.168.1.25 要对 192.168.2 的所有主机发送数据,则对 192.168.2.255 发送数据包即可。

全局地址和私有地址

OK,上面其实我一直用的是 私有地址 来做示例,那有哪些范围属于 私有地址,一般规定如下:

A类:10.0.0.0 ~ 10.255.255.255(10/8)

B类:172.16.0.0 ~ 172.31.255.255(172.16/12)

C类:192.168.0.0 ~ 192.168.255.255(192.168/16)

那么不在以上范围内的,均属于 全局地址

而在连接互联网的时候咧,我们在所在的网络里边只需要有一台机器可以连接互联网,即可使用 NAT技术私有地址全局地址 进行互换,即可实现局域网内所有计算机可以进行联网的需求。这也就很好的解决了 全局地址 将要枯竭的问题。

而全局地址一般由 ISP 进行动态提供,在联网那一瞬间将会获取一个可用的 IP全局地址,然后进行联网。

路由控制

OK,说了这么多关于 IP 的东西,我们也知道了可以将 IP 随意的切分 网络标识(也就是常说的网段),那么大概到这里就需要路由器来参与我们数据的传输了。

可以这么说,每个设备都有一个自己的路由表,比如当前我电脑上的情况:

MacOS路由表查询

可以看到一个 default 的路由,那么无论什么 IP,如果没有在下面列出来的话,就会发送至这个路由器中,然后路由器再继续的根据他目前存储的路由表进行线路的路由。

via《图解TCP/IP》

甚至我们可以查看我们访问一个地址的时候,跳转了多少路由:

1
traceroute liweidan.cn

traceroute结果

***** 表示被防火墙屏蔽了,得不到一些具体的数据。

最大传输单元MTU(Maximum Transmission Unit)

鉴于之前说过现在大多数的连接方式是使用以太网的链路进行传输,并且说过了一个以太网帧能够容纳的数据大小大概为 1500字节

所以当我们在内网将大的数据包比如说 5000字节 发送给路由器的时候,路由器就需要进行分包再通过以太网帧发送出去,而如果请求路径中有更小的 MTU 的时候,中间商的路由器又需要对已经分包号的数据包进行分包,这会导致很多性能浪费在路由器上面。

所以现行的规范基本规定,发送端 去自动发现路径中最小可传的 MTU 并且将这些 数据包 依据这个 MTU 进行分割以后再进行发送(木桶定理),这样途中所经历的所有路由器,将不再需要对数据进行分割,一次性提升传输性能。

步骤大致如下:

  1. 发送端发送一个 5000字节 的数据给路由器,路由器直接拒绝丢包,并且通过 ICMP协议 告诉发送端:最大处理1500字节
  2. 发送端重新整理数据,分包,一个一个发送给路由器。

发送端将会缓存这个 最大MTU值,时长则需要根据不同系统而定。

MacOS默认的MTU

IPv6

上面一直说的 IP 其实是 IPv4 的协议内容,因为 IPv4 地址的枯竭,所以急需要另外一种协议来替代 IPv4,所以 IPv6 就是解决 IP地址 不足的问题的。

怎么解决呢,加长度……IPv6128位 的,相比 IPv4,其容量扩大至 4倍

IPv6标记方法

IPv4 是由 4个 8位 组成的,所以可以标记 4个 正整数。但是如果 IPv6 需要表示 16 个正整数的话,就显得有点麻烦:我的IP地址是 192.168.1.7.192.168.1.7.192.168.1.7.192.168.1.7

所以,就使用 16进制 的形式进行表示,分别是每 2个8位 作为一组表示出来,如果中间连续出现多个 16进制位0 的话,还可以使用两个 : 进行表示(但是一个地址中只允许省略一次,毕竟省略多次就无法推算了嘛)。

比如:FEDC:0:0:0:8:3210:200C:417A

那省略的写法就是:FEDC::8:3210:200C:417A

IPv6地址组成部分

IPv6 有多种使用方式:

  • 唯一本地地址:局域网中可以使用,生成一个随机数融合到地址当中;

  • 链路本地单播地址:不使用路由器的情况下,可以直接使用 链路本地单播地址 进行通讯;

  • 全局单播地址:即互联网上分配的唯一 IP地址

一个 IPv6地址前64位 属于 网络标识后64位 属于 主机标识。其中,网络标识 还包含了 全局路由前缀子网ID,而 主机标识 保存着 64位比特版MAC地址,当然如果不愿意被识别设备,还可以将这个 MAC地址 通过随机生成的方式进行保存(操作系统的工作)。

而如果是 链路本地单播地址 的话,前64位 则没有保存什么实质性的内容,这 64位 中前面 10位 做了标记,而后面的 54位 则填充 0

以至于 MTU,默认均以 1280字节 进行分片然后发送数据。

IP数据包的内容

现在我们主要了解一下 IPv4 的数据包长什么样即可,但是由于内容还是比较多的,无论是一行或者一列都无法表示完整,所以使用表格从左到右从上到下的进行表示吧(貌似很多资料都是这样的),图中横向一个单元格表示 1个比特位,不是字节哦:

IP数据包图示

  1. 版本Version:占用 4个比特位IPv4 则填写 4IPv6 则填写 6
  2. 首部长度Internet Header Length:占用 4个比特位 ,这个字段所表示数的单位是32位字长(1个32位字长是4字节),也就是说如果四位是 1111 的话,表示十进制15,首部长度就达到60字节(15 * 4 = 60),并且这个数字永远是 4 的倍数,如果 IP头部数据 不足 4 的倍数的话,利用下面的 填充位 进行填充;
  3. 区分服务:这个值通常没有被使用,因为控制起来很麻烦,内容表示有 优先度最低时延 等通讯质量,后期有人提出使用 6位长的DSCP段 + 2位长的ECN段DSCP字段 的值越大表示优先级越高,而 ECN 分为两位,主要服务于上一层的协议;
  4. 总长度:顾名思义表示 整个IP包 的长度,占用 16位,可以表示到 65535 字节的长度(当然目前永远都不会有这么长);
  5. 标识:占用 16个比特位,跟下面的 源IP地址目标IP地址 共同识别分片,如果三个值一样,表示是同一个数据包的分片;
  6. 标志:用来标记分片情况,占用 3个比特位,第一位填充 0,第二位则表示是否可以分片 0表示可以1表示不可以,第三位则表示当前这个包是否是最后的一个数据包 0表示最后一个分片包1表示中段的包
  7. 片偏移量:占用 13个比特位,表示当前这个包在用户数据起点后的第几位开始,注意的是这个值表示多少个 8位,比方说 13个比特位 全部都是 1,表示 8192,则表示原始数据起点的 *8192 * 8 = 65536* 的位置开始,所以除了最后一个分包,其他用户数据的位置均在 8的倍数 中切割;
  8. 生存时间:之前是指定在 路由器 跳转中的总时间,如果时间小于 1,则将这个数值减去 1。而现在基本指定的是在网路中跳转路由器的次数(路由器中的一跳),由于占用 8位,所以可以表示的最大值是 255,如果超过这个值,路由器则会将这个数据包给抛弃掉;
  9. 协议Protocol:指的是数据部分的上层协议,用于 IP协议 处理器可以判断交给哪个程序进行处理;
  10. 首部校验和:占16位。这个字段只检验数据报的首部,但不包括数据部分;
  11. 可选字段:一些其他功能的选项,1 - 40位不等,后面的位数用 0 进行填充,填充到长度为 4 的倍数

— 分割线 —

以下均为辅助 IP协议 的一些技术

DNS技术

由于使用 IP地址 来记忆实在是太麻烦了,所以人类又发明了一项技术:DNS解析 用以映射 域名IP地址 的关系。我们从浏览器输入一串域名比如 https://ssn.liweidan.cn,那么浏览器会先在本机 hosts 文件搜索有没有映射的 IP地址,如果没有,则会跑去 DNS服务器 进行搜索,从而返回 IP地址 再进行资源的访问。

目前我们常见的顶级域名就有 comcnnet 等等,由 ICANN(一个非盈利的Internet管理组织) 托管,而我们国家会管理着 cn 域名的注册信息,那我们请求一个域名,就会将请求转移到 ISP 的服务器中,ISP 为了加快响应速度,则会缓存所有已经被请求过的域名映射记录,但是这里有个缺点,就是如果我们修改域名的解析记录的话,同步到各地区的 ISP 需要一定的时间,这也就是为什么我们修改一条解析记录通常会提示生效需要 2小时 左右。

由于解析记录有是多种,有 A记录 MX记录 CNAME记录 TXT记录 等等,那这里只列举常用的几个:

域名解析

A记录:用于映射域名跟 IP地址

CNAME记录:用于将域名映射到另外一个域名的记录;

MX记录:映射邮件服务器的记录(如果有域名可以映射到QQ邮箱,QQ邮箱中使用个人域名作为域名邮箱

ARP技术

那么根据之前所说的数据链路传输所说,发送数据是需要知道对方的 MAC地址 的,但是我们现在是在上面套了一层 IP地址,那就需要 ARP技术 来拿到对应的 MAC地址 了,这个方式有点像上面的 DNS解析

怎么获取咧,就是当前如果在缓存中找不到 IP地址MAC地址 的对应记录,就需要对网络中所有的设备发送一个 ARP包,当目标地址的设备拿到这个 ARP包 的时候将会将结果响应回去,而如果匹配不到当前的机子,则会将这个 ARP包 抛弃掉。

那为啥中间还要套一层 IP层 咧,直接用 MAC地址 不行咩,那就要涉及到我们上面所说的 IP分段 技术了,这一项技术是在 IP协议 层实现的,所以有必要套这一层,要不然我们要获取一个 MAC地址 就需要向全世界每一台计算机发送 ARP包 了。当然连接了 路由器 的话,第一条请求到的 MAC地址 就是 路由器 的了,并非目标计算机的 MAC地址

IPv6 无法使用这些技术,需要用 ICMPv6 来获取。

RARP

常用于小型的机器例如打印机需要获取自己的 IP地址 的情况(或者其他不支持 DHCP 的设备),打印机发送自己的 MAC地址RARP服务器 询问 IP地址,从而将返回的信息设置为自己的 IP

ICMP信息描述

这个可以理解为 Java 中的 异常信息栈,指出 数据包 在发送过程中遇到了什么问题,为什么没有到达目的地,封装成 ICMP通知消息 给发送端,通常用于辅助调试网络设备。

也可以用于 TTL超时 的时候返回错误信息,也可以用于判断发送的数据包是否已经成功到达对端(常用的 ping 就是基于这个技术实现的)

IP自动分配–DHCP

一般现在的 路由器 都内置了 DHCP服务器 的功能,用于设备开机联网的时候可以询问 IP地址 子网掩码 等必要的联网信息,并且会定时的延长 IP地址 的使用期限。

NAT

NAT(Network Address Transfer) 是一项本地网络使用私有地址,而联网的时候将私有地址转换为 全局IP地址 的一项技术。而且在传输层的 TCPUDP 还出现了 NAPT(Network Address Ports Transfer) 用于转换端口的技术。NAT技术 实则是为了解决 IPv4地址 枯竭而发明的,也正是现在用的最多的技术。

按照这个逻辑,那当然还是交给 路由器 啦(心疼路由器)。它内部会生成一张表,用来转换 私有地址全局地址。当然如果 IP地址 的转换还不够用的话,那估计还需要将 端口 参与一起转换(此时使用的是 NAPT

尔后为了 IPv4IPv6 的转换,又有了一项信息的 NAT 规范:NAT-PT

但是普通的 NAT技术 并没办法让外部服务器连接内部服务器,所以又出了一项 NAT穿越 的技术,就好像我们日常调试公众号的时候,可以使用一些软件将外部的请求重定向到我们本机进行调试一样。

IP隧道

IP隧道 一般架设在 两个IPv6网络之间,由于 两个IPv6网络之间 需要通讯,但是他们中间只有一个支持 IPv4 的网络连接,就可以使用 IPv4包着IPv6 的方式,将数据传输过去。发送端使用 IPv4协议 用户数据包着 IPv6 的所有数据(包括 IP头部),接收端再将外壳(IPv4)拆掉,用 v6 的方式进行解析即可。

其他IP协议

IP多播相关技术MLD,通知路由器表示自己想要接收多播消息,以及向集线器请求接收多播的地址;

IP任播:发送一个请求,被不定向的服务器接收,比如我们在请求 DNS解析记录 的时候,就需要发送一个任播请求,响应的可以是地区的 DNS服务器,也可以是其他的比较接近的服务器(最靠近那个宕机的情况)

通信质量控制QoS 用于衡量 IP传输 质量的参数。IP协议 一般只负责 尽力传输,而如果遇到路由器的 Buffer 过大导致宕机,则会引起丢包的问题。所以使用 QoS 参数进行衡量。当发生网络拥堵时,可以使用 ECN 来显式通知发送端,一般存在返回的 TCP 首部中,记录在发送出去的 IP首部,网络层和传输层共同协助实现拥塞通知的功能。

Mobile IP:手机肯定是不断移动的设备,但是如果每移动到一个地方就需要重新获取 IP地址 将会对上层传输层的开发造成很大的麻烦,所以我们就需要一个固定不变的 IP地址,所以就需要使用到 IP隧道 类似的技术,将数据进行转发。移动设备分配到的 IP地址 属于归属地址,而每个地方有不同的 归属代理,会进行 分配到的IP地址归属到的IP地址 进行转换,从而有一种即使移动了换了 代理 了,但是 IP地址 也没有进行改变的错觉。

小结

阐述了 IP地址 的组成结构,IP数据包 的内容,但是这些并不完成 重发 校验 等功能,只负责最大能力的 运输数据,而 重发 校验 可以说是能够传输数据后保证数据完整性的重中之重,但是这些内容将放在 传输层 进行处理。那就有 TCPUDP 协议的诞生,下节再说吧。