Linux网络编程:IP协议

目录

[一. IP协议的功能](#一. IP协议的功能)

[二. IP协议报头](#二. IP协议报头)

[2.1 IP报头的格式](#2.1 IP报头的格式)

[2.2 IP报头各部分含义](#2.2 IP报头各部分含义)

[三. IP报文的分片问题](#三. IP报文的分片问题)

[3.1 什么是分片](#3.1 什么是分片)

[3.2 分片的原理](#3.2 分片的原理)

[3.3 合并报文](#3.3 合并报文)

[四. 网段划分](#四. 网段划分)

[4.1 网络号和主机号](#4.1 网络号和主机号)

[4.2 网络号和主机号的划分策略](#4.2 网络号和主机号的划分策略)

[4.3 特殊的IP地址](#4.3 特殊的IP地址)

[4.4 IP地址数量不足问题](#4.4 IP地址数量不足问题)

[五. 公网IP和私网IP](#五. 公网IP和私网IP)

[六. 路由](#六. 路由)

[七. 总结](#七. 总结)


一. IP协议的功能

IP协议是TCP/IP五层模型的网络层所用到的协议,IP协议解决的问题是报文路由路径的选择。如图1.1所示,主机C要将数据送到主机B,报文随经过的路径为:主机C -> 路由器H -> 路由器F -> 路由器C -> 路由器D -> 主机B。选择上面这条路由路径,就是IP协议所做的工作。

++**IP协议的工作:**进行路由路径的选择。++
图1.1 IP协议进行路由路径的选择

对于IP协议,有如下几个基本概念:

  • **主机:**配有IP地址。但无法进行路由控制的设备。
  • **路由器:**配有IP地址,并且可以进行路由控制的设备(从广义上讲路由器也可以归为主机)。
  • **节点:**主机和路由器的统称。

二. IP协议报头

2.1 IP报头的格式

2.2 IP报头各部分含义

  • **4位版本号:**均视为Ipv4即可(部分内网采用Ipv6)。
  • **4位首部长度:**大小范围是0~15,用于标识20bytes定长报头和选项的总字节数,以4bytes为基本单位,20bytes+选项长度 = 4位首部长度 * 4。
  • 8位服务类型: 包括3位优先权字段(现已弃用)、4位TOS服务类型标识、1位保留(必须置为0),其中4位TOS服务类型标识包括:最小延时、最大吞吐量、最高可靠性、最小成本。++这4种TOS服务类型相互冲突,只能选择其中之一++。
  • **16位总长度:**IP报文的总长度,数据长度 = 16位总长度 - 4 * 4位首部长度。
  • **16位标识:**用于区分报文的唯一性,如果两个IP报文由一个报文拆分而来,那么他们的16位标识是相同的。
  • **3位标志:**用于IP报文分片,其中第一个标志暂时保留不用、第二个标志为禁止分片(如果这个标准被置1,且报文过长超出了数据链路层传输限制,那么该IP报文直接被丢弃)、第三个为更多分片标志位(如果该IP报文被分片,且当前报文不是被分片前的报文的最后一片,那么该标志位被置为1)。
  • **13位片偏移:**配合更多分片标志位来使用,表示被分片后的报文起始位置相对于原报文的起始位置的偏移量。
  • 8位生存时间(TTL): 数据到达目的主机最多经过的路由器数(最多跳数),++报文每次经过一个路由器,TTL-=1,如果TTL到达0报文还没有被送到目的主机,那么该报文就被丢弃了++。由于现实中网络状况极为复杂,任何人都无法完全理清报文的转发途径,理论上可能存在"环路转发"的情况,通过设置TTL限制报文经过的路由器数目,可以避免数据滞留在网络中造成网络崩溃问题。
  • **8位协议:**UDP协议或TCP协议。
  • **16位首部检验和:**用于检查报文合法性,如果检验不通过,那么该报文直接被丢弃。
  • **32位源IP:**发送数据的主机IP地址。
  • **32位目的IP:**接收数据的主机IP地址。

三. IP报文的分片问题

3.1 什么是分片

在数据链路层,由于物理层条件的限制,一般无法转发太大的报文,数据链路层一次转发报文的限制一般为(1500bytes,MTU)。因此,如果IP报文过大,那么就需要将IP报文分片,将一个IP报文拆分为多个报文进行转发。

IP报文报头中存在16位标识,就是用于区分两个报文是否是一个报文拆分而来的,如果是,16位标识就相同。

图3.1展示了IP报文拆分的原理,IP报文实在源主机的网络层拆分的,也要在目的主机的网络层合并,至于上面的传输层及下面的数据链路层,则完全不关心报文分片问题。
图3.1 IP报文的拆分与合并

3.2 分片的原理

IP报文的分片大小,受数据链路层传输限制的影响。对于一个分片的报文,报头中的"更多分片"标志位为1或者13位片偏移不为0两个条件至少满足其中之一。假设一个大报文被分为了10片:第一个分片后面还有9个分片,更多分片标志位为1,13位片偏移为0;最后一片(第10片)后面没有分片了,更多分片标志位设为0;13位片偏移不为0;中间位置的报文13位片偏移非零,更多分片标志位为1。

举一个demo示例(见图3.2),假设网络层有一个大小为3000bytes的报文,没有选项,数据链路层一次传输的数据量最多为1500bytes,那么我们可以按照下面的逻辑理解分片:

  • 第一次分片:提取原来报文头部的1500bytes内容(包含报头),由于后面还有两个分片,更多分片标志位为1,13位片偏移为0。
  • 第二次分片:报文中还剩1500bytes的数据,但是每次拆分出来的报文都要重新添加报头,报头占用20bytes,所以第二次分片只能拿走1480bytes的数据,还剩20bytes要在分为1片,因此更多分片标志位设为1,13位片偏移为1500。
  • 第三次分片:还剩20bytes的数据,这20bytes相对于原报文起始位置偏移2480bytes,因此13位片偏移为2480,该分片后面不再有更多报文,因此更多分片标志位设为1。

图3.2 IP报文的分片原理

3.3 合并报文

如果源主机在网络层对IP报文进行了分片,那么对端主机就要对分片后的报文进行了合并,对于报文合并,有三个问题需要解决:

  1. 如何识别一个报文是否进行了分片。
  2. 如何合并分片后的报文。
  3. 异常检测:如果N个分片的其中一个或多个丢失,那么如何识别出来。

如何识别一个报文是否进行过分片: 要综合"更多分片"标志位和13位片偏移来识别一个报文是否被分片,++报文没有被分片的条件为:更多分片标志位为0 && 片偏移为0++。

如何合并分片后的报文: 检测到了报文分片后,根据16位标识,确定那几个片来自同一个原始IP报文,++根据:片偏移 + 本报文长度 - 新增报头长度(如果有) = 下一报文片偏移 的规律对收到的分片报文进行排序,恢复出原始报文++。

如何进行异常处理: 如果分片后的报文其中之一发生了丢包问题,那么就认为整个报文发生了丢包,++从前到后检测 片偏移 + 本报文长度 - 新增报头长度(如果有) = 下一报文片偏移 是否一直成立,如果在某个位置处检测到了不成立,那么就丢弃整个(原始)报文++,如果采用的是TCP协议,那么就由TCP协议的可靠性保证机制来重发报文。

正是因为被分片后的报文只要其中之一发生丢包,那么就认为整个报文发生了丢包,因此++分片是一种不推荐的行为,因为这会大大增加丢包的概率++。

四. 网段划分

4.1 网络号和主机号

一个32位的IP地址可以分为两部分:网络号和主机号。

  • 网络号:用于标识IP地址所处的网段,不同网段的网络号各不相同。
  • 主机号:位于同一网段的设备的IP网络号相同,主机号不同。

一般来说,一个I地址的高N位属于网络号,低32-N位属于主机号。在不同的网络中,网络号和主机号的位数是不固定的。例如:如果把全球视为一个大型广域网,每个国家或地区属于一个网段,那么有可能前8位属于网络号(全球一共200多个国家和地区),后24位属于主机号;又比如将中国境内的每个地级市的网络归为一个网段,那么有可能前20位都是网络号,后面12位是主机号。

**结论:**32位IP地址中,主机号和网络号的位数是不固定的。
图4.1 网络号和主机号

4.2 网络号和主机号的划分策略

在早前,曾经有人提出过将IP地址划分为ABCDE五类,如图4.2所示。
图4.2 早期提出的ABCDE类IP地址

但是,这种划分方法存在一个明显的问题,A类IP所能容纳的主机数量明显多余B类和C类IP,A类IP经常存在被某个网段申请了后有许多剩余的IP没有被特定主机占用,而大多数组织都会去申请B类网络,从而造成B类网络资源不足的问题。而且,这种网络号划分方法将网络号长度限定死了,无法灵活动态调整,因此,现代网络通信已经极少使用这种IP地址划分方法了。

现代网络通信中一般采用CIDR方法(Classless Interdomain Routing)划分网络号:

  • 这种方式引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。
  • 子网掩码是一个32位整数,通常以一串0结尾,这串0对应的二进制位就是主机号。
  • 将IP地址与子网掩码按位与,就可以得到网络号 ,即:网络号 = IP地址 & 子网掩码。

++CIDR技术:通过子网掩码划分网络号。++

表4.1为一个子网掩码划分IP地址的案例,假设IP地址为192.168.24.112,子网掩码为255.255.255.0,那么 192.168.24.112 & 255.255.255.0 = 192.168.24.0,我们就认为网络号为192.168.24。

++结论:网络号 = IP地址 & 子网掩码++

| IP地址 | 192.168.24.112 |
| 子网掩码 | 255.255.255.0 |
| 网络号 | 192.168.24.0 |

网络号对应IP范围 192.168.24.0 ~ 192.168.24.255

4.3 特殊的IP地址

  • 如果主机号对应二进制位全部为0,那么这个IP就表示一个局域网。
  • 如果主机号全部设置为1,那么这个IP就表示广播IP,数据会被同一数据链路层的所有设备都收到。
  • 127.*表示本地换回IP,用于在本地进行测试使用,一般使用127.0.0.1。

4.4 IP地址数量不足问题

综和上面的内容,我们发现32位IP地址最多表示40多亿台计算机设备,但是全球的计算机设备数量已经远远超过这个数字,且由于网络号和主机号的划分,难免会造成IP地址浪费的问题,如果全世界真的每台计算机设备都有一个独立的IP,那么IP资源是肯定不够的,但是全球互联网依旧没有崩溃。

通过以下3种方法解决IP地址不足问题:

  1. 动态IP地址分配DHCP:只给接入网络的设备分片IP地址,设备退出网络就归还IP资源。
  2. NAT技术:允许不同私网中的两台计算机设备有相同的IP地址。
  3. ipv6技术:理论上可以彻底解决IP地址资源不足的问题,但很遗憾ipv4和ipv6不兼容,且ipv6技术出现之前ipv4已经被大范围使用,因此ipv6技术并未被广泛使用。我国由于人口众多,经济发展快速,需要更多的计算机设备实现快速通信,因此我国一直在大力推广ipv6技术,但是进展缓慢。

**DHCP技术:**自动给子网内新增的主机节点分配IP地址, 一般路由器均有DHCP技术。

**NAT技术:**源IP在不同内网、不同层级之间网络节点中转发,不断被替换的技术。

五. 公网IP和私网IP

用于某个组织内部的局域网,如果不与公网进行通信,那么一般使用私网ip,RFC 1918规定了以下3类IP地址为私网IP:

  • 10.*,前8位是网络号。
  • 127.16.* ~ 172.31.*,前12位是网络号。
  • 192.168.*,前16位是网络号。

在上面范围内的IP地址为私网IP,范围之外的全部公网IP。

一个路由器有两个IP,分别为子网IP和WAN IP,其中WAN IP表示上一层网络的IP地址。图5.1为公网IP和私网IP的划分示意图,我们可以观察到,在不同私网中(运营商路由器和家用路由器分别组件私网),是可以存在相同的IP地址的,在同一网段中则不允许有相同的IP地址,同一网段(私网)中的设备通信不受上级网络的干扰,这样就可以达到多设备占用同一IP的目的,可用于解决IP地址不足的问题。
图5.1 公网IP和私网IP的划分

根据图5.1,给出如下的结论:

  • 一个路由器可以配置两个IP地址,其中一个为WAN IP,另一个为子网IP,路由器WAN IP用于与上级网络设备相连接,子网IP的主机号一般为1。
  • 在同一个子网中,不允许出现相同的IP地址,但是在子网之间(不同子网)允许有相同的IP地址。
  • 家用路由器,要与运营商路由器相连接,运营商路由器可以将家用主机中的数据推送到公网上,以达到在家访问工网的目的。
  • ++数据每次经过一个路由器,都会将源IP地址替换为路由器的WAN IP++,这种技术称为NAT(Network Adress Translation),可用于解决IP地址不足。
  • 如果希望我们个人写的程序可以在公网上被访问到,那么就需要将程序部署到一台具有公网IP服务器上。

六. 路由

所谓路由过程,就是数据在网络中转发,在每个节点中"问路的过程"。

数据从A主机转发到B主机,如图6.1,要经过从A主机的应用层到数据链路层,经过B主机的数据链路层到应用层,至于中间经过的若干个路由器,则只要经过它们的数据链路层和网络层,路由的过程,就是在网络层中实现的。
图6.1 路由过程中数据经过的层级

图6.2展示了数据在网络传输过程中的路由过程,假设主机A发送数据到主机B要经过路由器1和路由器2,那么主机A就要先查询路由表,将数据送到路由器1,到路由器再查找路由表送到路由器2,路由器2的路由表中存在目的主机B的IP,那么下一条就直接将数据送到主机B,数据送达,路由过程结束。
图6.2 路由过程示意图

路由过程设置两个关键要素:网络号 + 路由表。

在Linux操作系统下,通过指令route,可以查看当前设备的路由表。

route指令:查看路由表。

图6.3为使用route指令查看路由表后看到的内容,其中每部分的含义如下:

  • Destiantion:目的设备的网络地址,其中default为默认地址,如果路由表中其余所有地址都没有匹配上,那就将数据转发到default设备中去。
  • Getaway:设备类型,getway表示为路由器。
  • Genmask:子网掩码。
  • Flags:标志,G表示下一条地址是路由器地址,U表示设备正在被使用。
  • Iface:转发接口,如果网络号匹配,那么就通过指定的Iface转发出去。

图6.3 通过route指令查看路由表

在路由过程中,根据如下方式,选择下一个路由节点:

  • 将目的IP地址与路由表中最后一行的子网掩码按位与操作,得到一个网络号,如果与Destination相匹配,那么就通过Iface将数据转发出去。
  • 如果不匹配,那就继续向上遍历,将目前IP依次与每个子网掩码按位与,直到获取相匹配的网络号将数据转发出去为止。
  • 如果到了default还没有找到相匹配的网络号,那么就讲数据转发到default设备上去。

下面利用两个具体的IP地址为例,以图6.4所示的路由表为参考,来理解通过路由表进行路径选择的流程。
图6.4 示例路由表

示例1 -- 将数据转发到192.168.31.233的流程:

  • 从路由表最后一行开始,将目前IP与子网掩码按位与操作,得到网络地址192.168.31.0,与Destination不匹配,向上一行查找。
  • 将目的IP与当前行的子网掩码按位与操作,得到网络地址192.169.31.0,与Destination相匹配,通过转发接口eth1将数据转发出去,至此下一节点选择结束。

示例2 -- 将数据转发到192.168.155.21的流程:

  • 从路由表最后一行开始,将目前IP与子网掩码按位与操作,得到网络地址192.168.155.0,与Destination不匹配,向上一行查找。
  • 将目的IP与当前行的子网掩码按位与操作,得到网络地址192.169.255.0,与Destination还是无法匹配,继续向上查找。
  • 此时到达了default查询接口,在此之前全部没有匹配的网络地址,因此直接通过转发接口eth0将数据发送到default设备中,至此下一节点选择结束。

七. 总结

  • IP协议是网络层的协议,负责将数据从源主机发送到目的主机过程中,转发路径(要经过哪些)节点的选择。
  • 由于数据链路层物理条件的限制,IP报文如果过大需要进行分片转发,分片是源主机网络层的工作,对端主机网络层负责组合。分片和组合过程中涉及报头的"更多分片"标志位及13位片偏移,根据16位序号来确定两个报文是否来自同一个原始报文。
  • 但是,报文分片是一种很不推荐的行为,因为被分片后的报文只要有一个发生了丢包,那么就相当于整个报文都丢了,这样会大大增加丢包的概率。
  • 一个32位IP地址被划分为两个部分:网络号和主机号。网络号表示设备所在的网段,主机号表示网段中特定的一个主机,不同网段的网络号一定不同,同一网段中的主机号一定不同。通过IP地址 & 子网掩码 的方式,可以获取网络地址。
  • IP地址被分为公网IP和私网IP,对于私网IP,则用于某个组织内部的通信,不与公网通信,在不同的私网中,允许有相同的IP地址出现。FRC 1918标准对私网IP做了规范。
  • 采用DHCP、NAT、Ipv6技术可以解决IP地址不足的问题,现实中一般采用NAT技术,所谓NAT技术,就是当报文经过路由器时,将IP报头中的源IP替换为路由器的WAN IP的技术。
  • 所谓路由,就是数据在网络中转发"问路"的过程,通过查询节点中存放的路由表,来确定下一跳的设备。
相关推荐
Hello.Reader3 分钟前
Git 安装全攻略Linux、macOS、Windows 与源码编译
linux·git·macos
龙仔7256 分钟前
华为云CentOS配置在线yum源,连接公网后,逐步复制粘贴,看好自己对应的版本即可,【新手必看】
linux·centos·华为云
tiging7 分钟前
centos实现SSH远程登录
linux·centos·ssh
苦学编程的谢35 分钟前
Java网络编程API 1
java·开发语言·网络
alien爱吃蛋挞1 小时前
【JavaEE】万字详解HTTP协议
网络·网络协议·http
好多知识都想学1 小时前
Linux 文件处理器 sed 和 awk 详细讲解
linux·运维·ubuntu
Johny_Zhao1 小时前
阿里云数据库Inventory Hint技术分析
linux·mysql·信息安全·云计算·系统运维
FBI HackerHarry浩2 小时前
云计算 Linux Rocky day05【rpm、yum、history、date、du、zip、ln】
linux·运维·云计算·腾讯云
Bright16683 小时前
mkcert实现本地https
网络协议·http·https
异常君3 小时前
Windows 与 Linux 虚拟内存机制对比:设计理念与实现差异
java·linux·windows