目录
一、基本概念
二、IP协议格式
三、分片与组装
四、网段划分
五、特殊IP地址
六、IP地址的数量限制
七、私网IP地址与公网IP地址
八、路由
九、路由表生成算法
IP协议全称为"网际互连协议(Internet Protocol)",IP协议是TCP/IP体系中的网络层协议
网络层解决的问题
TCP作为传输层控制协议,其保证的是数据传输的可靠性和传输效率,但TCP提供的仅仅是数据传输的策略,而真正负责数据在网络中传输的则传输层之下的网络层和链路层
保证数据可靠的从一台主机送到另一台主机的前提
当双方在进行基于TCP的网络通信时,要保证将数据可靠的从一台主机送到另一台主机,前提是发送方要有将数据送到对方主机的能力
在网络层有能力将数据送到对方主机的情况下,虽然网络层不能保证每次都能将数据成功送到对方主机,但在TCP提供的可靠性策略的保证下,最终网络层就一定能够将数据可靠的发送到对方主机
注意:
路径选择
数据进行的网络传输一般都是跨网络的,而路由器就是连接多个网络的硬件设备,因此数据进行跨网络传输时一定会经过多个路由器
数据路由当确定了要到达的目标主机后,就需要寻找最短的路径到达该目的地。目的地的确定是非常重要的,目的地直接决定了数据路由时的路径选择,这也是跨网络找到目标主机的根本。只有数据经过了较为正确的路径选择,最终才可能慢慢趋近于目标网络或目标主机
确定数据路由的目的地后,数据就可以在网络中进行路由了,但数据在路由时无法自行进行路径选择,因为数据本身是"不认识路"的,因此数据在路由的过程中需要不断"找路人问路","路人"就是网络中的一台台路由器
网络中的路由器是"认识路的",其"认路经验"都记录到路由表中,因此路由器可以通过查路由表找到去特定点的最短路径。因此数据在路由时,会不断通过路由器来进行路径选择,以此来一步步靠近目标网络或目标主机
主机和路由器
IP报头在内核中本质是一个位段类型,给数据封装IP报头时,实际就是用该位段类型定义一个变量,然后填充IP报头中的各个属性字段,最后将这个IP报头拷贝到数据的首部,至此便完成了IP报头的封装
IP如何将报头与有效载荷进行分离?
P分离报头与有效载荷的方法与TCP相同,当IP从底层获取到一个报文后,虽然IP不知道报头的具体长度,但IP报文的前20个字节是IP的基本报头,并且这20字节中涵盖4位首部长度
因此IP是这样分离报头与有效载荷的:
IP如何决定将有效载荷交付给上层的哪一个协议?
基于IP协议的传输层协议不止一种,因此当IP从底层获取到一个报文并对其进行解包后,IP需要知道应该将分离后得到的有效载荷交付给上层的哪一个协议。
在IP报头中有一个字段叫做8位协议,该字段表示的就是上层协议的类型,IP就是根据该字段判定应该将分离出来的有效载荷交付给上层的哪一个协议。该字段是发送方的IP层从上层传输层获取到数据后填充的,比如是上层TCP交给IP层的数据,那么该数据在封装IP报头时的8位协议填充的就是TCP对应的编号
32位源IP地址和32位目的IP地址
IP报头中的32位源IP地址和32位目的IP地址,分别代表的就是该报文的发送端和接收端对应的IP地址
数据在网络传输过程中会遇到一个个的路由器,这些路由器会帮助网络当中的数据进行路由转发,使得网络中的数据慢慢趋近于目标主机。路由器在帮助数据进行路由转发时,会提取出该数据的IP报头中的目的IP地址,并以此作为数据路由转发的重要依据
当接收端收到了发送端发来的数据后,接收端可能也想要给发送端发送数据,因此发送端在发送数据时除了需要指明该数据的目的IP地址,还需要指明该数据的源IP地址,即发送端的IP地址。即便接收端收到数据后没有数据想要发送,但至少需要向发送端发送一个响应报文,表明发送端发送的数据已经被接收端可靠的收到了
8位生存时间
报文在网络传输过程中,可能因为某些原因导致报文无法到达目标主机。如报文在路由时出现了环路路由的情况,或者目标主机已经异常离线了,此时这个报文就成了一个废弃的游离报文
为了避免网络中出现大量的游离报文,于是在IP的报头中就出现了一个字段:8位生存时间(Time To Live,TTL)。8位生存时间代表的是报文到达目的地的最大报文跳数,每当报文经过一次路由,生存时间就会减一,当生存时间减为0时该报文就被自动丢弃,在网络中消散
数据链路层解决的问题
IP能够将数据跨网络从一台主机送到另一台主机,而数据在进行跨网络传送时,需要经过一个个的路由器进行路由转发,最终才能到达目标主机。如要将数据从主机B跨网络传送到主机C,那么主机B需要先将数据交给路由器F,路由器F再将数据交给路由器G,…,最终由路由器D将数据交给主机C
IP进行数据跨网络传送的前提是,需要先将数据从一个节点传送到和自己相连的下一个节点,这个问题就是由IP网络层之下的数据链路层解决的,其中数据链路层最典型的代表协议就是MAC帧。而两个节点直接相连也就意味着这两个节点是在同一个局域网中的,因此要讨论两个相邻节点的数据传送时,实际讨论的就是局域网通信的问题
最大传输单元 MTU
MAC帧作为数据链路层的协议,会将IP传下来的数据封装成数据帧,然后发送到网络中。但MAC帧携带的有效载荷的最大长度是有限制的,即IP交给MAC帧的报文不能超过某个值,这个值就是最大传输单元(Maximum Transmission Unit,MTU),这个值的大小一般是1500字节
使用ifconfig命令可以查看对应的MTU
由于MAC帧无法发送大于1500字节的数据,因此IP层向下交付的数据的长度不能超过1500字节
分片与组装
若IP层要传送的数据大于1500字节,那么就需先在IP层对该数据进行分片,然后再将分片后的数据交给下层MAC帧进行发送
若发送数据时在IP层进行了分片,那么分片数据到达对端主机的IP层后就需先进行组装,然后再将组装好的数据交付给上层传输层
注意:
数据的分片和组装都是由IP层完成的
数据的分片和组装都在IP层完成,上层的传输层和下层的链路层并不关心
数据的分片和组装完全是由IP协议自行完成的,传输层和链路层不必关心也不需要关心
分片过程
假设IP层要发送4500字节的数据,由于该数据超过了MAC帧规定的MTU(1500字节),因此IP层需先将该数据进行分片,然后再将一个个的分片交给MAC帧进行发送。IP报头若不携带选项字段,那么其大小就是20字节,假设IP层添加的IP报头的长度就是20字节,并按下列方式将数据分片后形成了四个分片报文
分片后的每一个分片数据都需要封装上对应的IP报头,因此4500字节的数据至少需要分为四个分片报文进行发送
分片报文到达对方的IP层后需要被重新组装起来,因此IP层在对数据进行分片时需要记录分片的信息,而IP报头中的16位标识、3位标志和13位片偏移实际就是与数据分片相关的字段。
上述四个分片报文对应的16位标识相同,假设四个分片报文的16位标识都是123,则这四个报文对应的16位标识、3位标志中的"更多分片"和13位片偏移分别如下:
13位片偏移中记录的字节数是当前分片在原数据开始处的偏移字节数的值÷8,如分片报文2在原始数据开始处的偏移字节数是1480,其对应的13位片偏移的值就是1480 ÷ 8 = 185
组装过程
MAC帧交给IP层的数据可能是经过分片后发送的,也可能是没有经过分片的,因此IP要通过某种方式来区分收到的各个数据
因此IP可以通过IP报头中的32位源IP地址和16位标识,将经过分片的数据各自聚合在一起,聚合在一起后就可以开始进行组装了
对于各个分片报文来说:
根据分片报文的这三个特点就能够将分片报文合理的组装起来
分片报文丢包的问题
分片报文在网络传输过程中可能会出现丢包问题,但接收端有能力判断是否收到了全部分片报文,假设某组分片报文对应的16位标识值为x:
未分片报文的"更多分片"标志位为0,最后一个分片报文的"更多分片"标志位也为0。但接收端只收到分片报文中的最后一个分片报文时,接收端不会将其识别成一个未分片的报文,因为未分片的报文所对应的13位片偏移的值应该是0,而最后一个分片报文所对应的13位片偏移的值不为0
因此只有当一个报文的13位片偏移为0,并且该报文的"更多分片"标志位也为0时,该报文才会被识别成一个没有被分片的独立报文,否则该报文就会被识别成一个分片报文
为什么不建议进行分片?
虽然传输层并不关心IP层的分片问题,但分片对传输层是有影响的
只要分片报文中的某一个出现了丢包,此时传输层都需要将数据整体进行重传,因为传输层并不知道底层IP对数据进行了分片,当传输层发送出去的数据得不到应答时传输层就只能将数据整体进行重传,因此数据在发送时不建议进行分片
如何尽可能避免分片?
数据分片的根本原因在于传输层一次向下交付的数据太多,导致IP无法直接将数据向下交给MAC帧,若传输层控制好一次交给IP的数据量不要太大,那么数据在IP层自然也就不需要进行分片
一般建议TCP将发送的数据控制在1460字节以内,此时就能够降低数据分片的可能性。之所以说是降低数据分片的可能性,是因为每个网络的链路层对应的MTU可能是不同的,若数据在传输过程中进入到了一个MTU较小的网络,那么该数据仍然可能需要在路由器中进行分片
IP地址的构成
IP地址由网络号和主机号两部分构成:
可以在IP地址的后面加一个 /,并在 / 后面加上一个数字,这就表示从头数到第几位为止属于网络标识
譬如,下图中路由器连接了两个网段。对于网络标识来讲,同一网段内主机的网络标识是相同的,不同网段内主机的网络标识是不同的。而对于主机标识来讲,同一网段内主机的主机标识是不同的,不同网段内主机的主机标识是可以相同的
若在子网中新增一台主机,则这台主机的网络号和子网的网络号一致,但是主机号不能和子网中的其他主机重复
DHCP协议
当连接WiFi时需要输入密码,本质就是因为路由器需要验证账号和密码,验证通过路由器就会动态分配一个IP地址,然后就可以基于这个IP地址进行各种上网动作
为什么要进行网段划分?
当IP要将数据跨网络从一台主机发送到另一台主机时,不是直接将数据发送到目标主机,而是先将数据发送到目标主机所在的网络,然后再将数据发送到目标主机。因此数据在路由时的第一目的并不是找到目标主机,而是找到目标网络所在的网络,然后再在目标网络中找到目标主机
数据路由之所以不一开始就以找目标主机为目的,是因为这样效率太低了
找主机的过程本质是排除的过程,若一开始就以找目标主机为目的,那么查找一次仅能排除一个主机。而若一开始先以找目标网络为目的,那么在查找过程中就能一次排除大量和目标主机不在同一网段的主机,可以提高检索的效率。为了提高数据路由的效率,对网络进行了网段划分
网段划分
过去曾经提出一种划分网络号和主机号的方案,即将所有IP地址分为五类
要判断一个IP地址是属于哪一类时,只需遍历IP地址前五个bit位,第几个bit位最先出现0值,那么这个IP地址对应就属于A、B、C、D、E类地址
子网划分
但随着网络的飞速发展,这种划分方案的局限性很快就显现出来
如一些学校、公司、实验室等组织想要申请自己的局域网,由于A类地址的网络号只占7个比特位,因此A类地址可申请的网络只有个,于是大多数组织都选择申请B类地址。由于B类地址的主机号占16个比特位,因此理论上一个B类网络中允许有65536台主机。但实际网络架设中,一般不会存在一个局域网中有这么多主机的情况,也意味着大量的IP地址都被浪费
为了避免这种情况,于是又提出了新的划分方案,称为CIDR(Classless Interdomain Routing):
此时一个网络就被更细粒度的划分成了一个个更小的子网,通过不断的子网划分,子网中IP地址对应的主机号就越来越短,因此子网中可用IP地址的个数也就越来越少,这也就避免了IP地址被大量浪费的情况
注意:子网划分不是只能进行一次,可以在划分出来的子网的基础上继续进行子网划分
因此一个数据在路由的时候,随着数据不断路由进入更小的子网,其网络号的位数是在不断变化的,准确来说其网络号的位数是在不断增加的,也意味着IP地址中的主机号的位数在不断减少。最终当数据路由到达目标主机所在的网络时,就可以在该网络中找到对应的目标主机并将数据交给该主机,此时该数据的路由也就结束了
并不是所有的IP地址都能够作为主机的IP地址,有些IP地址本身就是具有特殊用途的
IP地址中主机号为全0的代表的是当前局域网的网络号,IP地址中主机号为全1的代表的是广播地址,这两个IP地址都是不能作为主机的IP地址的。因此在某个局域网中最多能存在的主机个数是 2^主机号位数 − 2
本机环回基本原理
本机环回会将数据贯穿网络协议栈,但最终并不会将数据发送到网络中,相当于本机环回时不会将数据写到网卡上
本机环回的目的就是将数据自顶向下贯穿协议栈,进行一次数据封装的过程的过程,然后再自底向上贯穿协议栈,进行一次数据的解包和分用,用于测试本地的网络功能是否正常
本机环回的基本原理:
IP地址数量不足问题
IP地址(IPv4)是一个4字节32位的正整数,因此一共有个IP地址,即将近43亿个IP地址。但TCP/IP协议规定,每个主机都要有一个IP地址
现在全世界人口已经有70多亿了,电脑、手机等都需要IP地址。随着科技的发展,智能手表、智能冰箱、智能洗衣机等设备若要入网也是需要IP地址的。并且IP地址并不是按照主机台数来配置的,因此一个主机可能需要多个IP地址,更别谈还有很多组网的路由设备也需要IP地址,以及一些特殊的IP地址不能使用的问题
43亿个IP地址其实早就不够用了,因此才提出了CIDR的方案对已经划分好的五类网络继续进行子网划分,其目的就是为了减少IP地址的浪费
CIDR虽然在一定程度上缓解了IP地址不够用的问题,因为CIDR提高了IP地址的利用率,减少了浪费,但IP地址的绝对上限并没有增加
如何解决IP地址不足问题
解决IP地址不足有以下几种方式:
私网IP地址的种类
若一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址
包含在这个范围中的,都被称为私网IP,其余的则被称为公网IP(或全局IP)
连接云服务器时,连接的IP地址即是公网IP
可以使用ifconfig命令来查看博主这台机器的私网IP,其中网络接口lo(loop)代表的是本地环回,而eth0代表的就是博主机器的网络接口,可以看到私网IP地址是10.0.8.2
由于博主使用的是腾讯云,因此这里的10.0.8.2是博主这台云服务器在腾讯内部的私网IP,可以看到这个IP正好在第一种私网IP范围内
数据是如何发送到服务器的
路由器是连接两个或多个网络的硬件设备,在路由器上有两种网络接口,分别是LAN口和WAN口:
LAN口的IP地址被称为LAN口IP,即子网IP;WAN口的IP地址被称为WAN口IP,即外网IP
由于私网IP不能出现在公网中,因此子网内的主机在和外网进行通信时,路由器会不断将数据包IP首部中的源IP地址替换成路由器的WAN口IP,这样逐级替换,最终数据包中的源IP地址成为一个公网IP,这种技术就是NAT(Network Address Translation,网络地址转换)
为什么私网IP不能出现在公网中?
不同的局域网中主机的IP地址可能是相同的,所以私网IP无法唯一标识一台主机,因此不能让私网IP出现在公网上,因为IP地址要能唯一标识公网上的一台主机
但由于IP地址不足的原因,不能让主机直接使用公网IP,而让主机使用私网IP,因为私网IP可以重复也意味着可以在不同的局域网使用相同的IP地址,缓解了IP的不足
两个局域网中的主机进行通信必须通过公网
所以数据要从一个局域网发送到另一个局域网,不经过公网是基本上不可能的。在和别人聊天的时候,也不是直接将数据从一个局域网直接发送到了另一个局域网,而是先将数据经过公网发送到了服务器,然后再由服务器将数据经过公网转发到了另一个局域网
但实际确实存在一些技术能够使数据包在发送过程中不进行公网IP的替换,而将数据正确送到目标主机,即内网穿透,也被称为NAT穿透
数据"问路"过程
数据在路由的过程中,实际就是一跳一跳"问路"的过程。所谓"一跳"就是数据链路层中的一个区间,具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间
IP数据包的传输过程中会遇到很多路由器,这些路由器会帮助数据包进行路由转发,每当数据包遇到一个路由器后,对应路由器都会查看该数据的目的IP地址,并告知该数据下一跳应该往哪跳
路由器的查找结果可能有以下三种:
路由表查询的具体过程
每个路由器内部会维护一个路由表,可以使用route命令查看云服务器上对应的路由表
当IP数据包到达路由器时,路由器就会用该数据的目的IP地址,与路由表中的子网掩码 Genmask进行"按位与"操作,然后将结果与子网掩码对应的目的网络地址Destination进行比对,若匹配则说明该数据包下一跳就应该跳去这个子网,此时就会将该数据包通过对应的发送接口Iface发出
若将该数据包的目的IP地址与子网掩码进行"按位与"后,没有找到匹配的目的网络地址,此时路由器就会将这个数据包发送到默认路由,即路由表中目标网络地址中的default。默认路由对应的Flags是UG,实际就是将该数据转给另一台路由器,让该数据在另一台路由器继续进行路由
数据包不断经过路由器路由后,最终就能到达目标主机所在的目标网络,此时就不再根据该数据包目的IP地址中的网络号进行路由了,而是根据目的IP地址中的主机号进行路由,最终根据该数据包对应的主机号就能将数据发送给目标主机了
路由可分为静态路由和动态路由:
路由表相关生成算法:距离向量算法、LS算法、Dijkstra算法等