【网络】IP协议详解

在这里插入图片描述
本篇博客由 CSDN@先搞面包再谈爱 原创,转载请标注清楚,请勿抄袭。

前言

本篇主要讲解:IP协议报头中的字段、网段划分、路由。

我前面的博客中已经讲了应用层和传输层的一些相关协议,比如应用层的HTTP和HTTPS,传输层的TCP和UDP(下图不考虑物理层):

在这里插入图片描述

本篇就要讲网络层的IP协议。
在这里插入图片描述

如果你是一个纯小白,建议先看看这篇:【网络】网络扫盲篇 ——用简单语言和图解带你入门网络

如果你对于HTTP、TCP、UDP不了解且想要深入学习一下,可以先看看下面三篇:
【网络】用代码讲解HTTP协议

【网络】对于我前面UDP博客的补充

【网络】想学TCP,这一篇就够了 —— TCP理论知识详解(基于前面手搓TCP服务端博客的补充)

本篇中涉及到HTTP、TCP、UDP的内容不会再详细讲。

正式开始

我在讲应用层的时候说应用层把数据传给了对端的应用层,但是实际上并没有真正的直接发送,而是向下传给了传输层;讲传输层的时候也是说把传输层的数据发给了对端传输层,实际上也是没有真正的发送,而是传给了下层的网络层。

在这里插入图片描述
在应用层,主要解决的是数据的使用问题。
在下三层中,主要解决的是网络通信的细节,将数据可靠的从A主机跨网络发送给B主机。可靠是由传输层保证的,网络层提供了把数据从A主机发送到B主机的能力。

问:网络层有这个能力,是否能代表一定能成功?
不一定,就像你们班有一个学霸一样,你可以说人家有能力考试的时候能考满分,但并不能说TA次次考试都能考满分。

有能力只能表明有非常高的概率能做成某一件事情,可能说考10次,7次考满分,2次考了98,一次考了99。如果教学主管想要让这个人某次的考试成绩能保证是满分,教学主管就可以让命题组多出几套题让其做,没有考满分就下一套,直到考到满分就把满分作为最终成绩。(虽然有点不现实)

这里教学主管就相当于传输层,学霸就是网络层。
传输层能够判断网络层是否发送成功,比如TCP的确认应答机制,如果没有发送成功就重传,如果还没收到就再重传,直到对端接收到为止,进而保证了一定能发送给对方。

所以将数据可靠的从A主机发送给B主机这句话,可靠性由传输层保证,从A发送到B由网络层保证。

在这里插入图片描述

数据每一跳发送到对端的过程就是数据转发的过程,其中每一跳都是根据IP地址来进行路线选择,所以目的IP选择了数据发送的目标。(这一点在我前面扫盲篇详细讲了,不懂的同学请先看看那篇)

几个概念:
主机: 配有IP地址, 但是不进行路由控制的设备;
路由器: 即配有IP地址, 又能进行路由控制;
节点: 主机和路由器的统称;

狭义上来说主机只是通信时两端的ABCD,其实路由器也可称为主机。

IP协议报文

先看长啥样:
在这里插入图片描述

学过TCP的同学是不是觉得这个报文很熟悉,TCP的报文长这样:
在这里插入图片描述

两个报文都是20字节固定长度报头,然后是报文的选项字段,然后就是数据。

其中20字节固定长度报头 + 选项就是完整报头,有效载荷就是数据。

报头都是用位段来实现,构建一个报头就是创建一个结构体对象,然后相关字段填一填就行。

任何一个协议都要考虑如何封装一个报文和如何分解一个报文,分解完后如何上交给上层。那么首先就来说说IP协议报文如何做到。

第一行

报文的封装和分离

再来看看报文长啥样:
在这里插入图片描述

想要分离,首先就是先读取20字节长度的固定报头,其中有一个字段为4位首部长度:

这个字段表示的是整个报文报头的实际大小,和TCP中的4位首部长度含义一模一样。

读到这个字段之后就能知道选项有多长了。

那确定报头中选项的长度呢?

很简单,4位首部长度的字段,假如说值为x,也就是说报头的总长度就是x,x - 20就能得到选项的长度(20为20字节的固定报头长度),但是有个问题,x只有4位二进制,那么范围就是0000 ~ 1111,换成十进制为:0 ~ 15,那么问题来了,最大才15,怎么减去20呢?

这里的首部长度,一个单位为4字节,也就是说x的范围换算成10进制其实是0 ~ 60。那么自然也就能减过了,算上固定长度的报头,那么整个报头的范围就应该是20 ~ 60,那4位首部长度范围应该为多少呢?两边同时除以四就行:5 ~ 15,二进制就是 0101 ~ 1111。

所以TCP解包的时候先提取出20字节,再根据标准报头提取出4位首部长度乘以4,假如说是y,若y为20就不需要再提取选项了,因为选项为空;若y大于20再让y减去20,得到选项长度,这样报头就读完了。

然后20字节报头中还有一个字段16位总长度:
在这里插入图片描述

这个字段表示的就是整个报文的大小。

所以剩下数据大小就是16位总长度字段的值 - 4位首部长度 * 4。

IP协议报文中的数据是传输层的数据段,假如说传输层用TCP,应用层用HTTP,那么IP协议的数据就是:
在这里插入图片描述

4位版本

在这里插入图片描述

4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4。

简单说一下IPV6是干啥的:
IPv6地址为128位,相比IPv4的32位,IPv6的地址空间更大,可以支持更多的设备和网络连接。IPv6的地址格式为8组16位的十六进制数,每组之间用冒号分隔。IPv6的地址空间大小为2的128次方,即约340万亿亿亿亿亿个地址,这足以满足未来互联网的需求。

我们经常听到IPV4已经分配完了,但是目前我们用的还是IPV4,因为用到了NAT技术,NAT后面再讲。

8位服务类型

在这里插入图片描述

8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要。

这里第一行就说完了,最重要的是4位首部长度和16位总长度,剩下的两个了解一下即可。

第二行先不说,等会再讲。

第三行

生存时间TTL

在这里插入图片描述

网络中可能因为路由器的bug,会导致报文在多个路由器之间来回转发,比如说这样:
在这里插入图片描述

这样就出现了死循环的情况。

或者是两台主机相隔距离太远了,不想让报文经过的路由器数超过n个,比如说15,只要报文经过了15个路由器就直接丢弃。

现在全世界范围的网络已经非常大了,虽然都统一采用TCP/IP,但是底层还是会有差异,包括厂商生产出来的硬件,路由算法等,没有一个人可以将全球网络的细节搞清楚。我们并不能保证网络中不存在某些数据黑洞,数据一进去就出不来了,比如说上面的路由器转发有问题,或者是线路有问题等。

所以针对上述这些许情况就需要给每个IP报文设置生存时间,不要让一个迷路的报文一直在网络中存活,不然浪费资源,如果这种迷路的报文不会消散,累计的多了肯定会导致网络要隔三差五瘫痪一次。这个生存时间就是报头中的8位生存时间TTL。

8位生存时间,就是一个计数器,经过一个路由器就要减1,当经过一个路由器时且该字段变为0时,就不再转发,而是直接丢弃。

检验和

在这里插入图片描述

IP报头检验和是用来检测IP数据报(网络层向数据链路层传递的报文用专业术语来说叫数据报)在传输过程中是否发生了比特位的改变或者损坏。

在传输过程中,IP数据报可能会因为一些硬件电路的问题导致某些比特位被修改,这会导致数据传输的错误。

IP报头检验和通过对IP数据报头部的所有比特位进行计算,生成一个校验和值,接收方可以通过重新计算校验和值来检测数据报是否被修改或者损坏。如果重新计算的校验和值与接收到的校验和值不一致,那么数据报就被认为是损坏的,接收方会丢弃这个数据报。

就算丢包也没关系的,上层有TCP可以重传。

8位协议

在这里插入图片描述

表示上层协议的类型,没啥说的。

第三行讲完了。

32位源IP和32位目的IP

在这里插入图片描述

这两个也没啥说的,就是表明数据从哪来到哪去,报文在路由转发的时候每个路由器都是工作在网络层的,就能看到报文中的IP地址,根据目的IP来进行转发。

端口是给传输层用的,IP是给网络层用的。

下面来说说第二行字段。

第二行

在这里插入图片描述

先不说具体字段。

数据分片

数据报可大可小,但是链路层由于物理原因,一般情况下无法转发太大的数据,其有一次性可以转发到网络的报文大小限制(MTU,后面再讲),不同链路截止类型的网络有不同的默认MTU值,拿以太网来说,MTU就是1500字节,假如网络层传下来一个2500字节的数据报,那么数据链路层会因为该数据报太大而无法转发,此时网络层就会对该数据报进行数据分片。

举个例子,寄快递的例子。

假如说你现在整了一台新电脑,旧的电脑(都是台式机)不想用了,但是你有一个表弟跟你关系很好,不过你表弟在郑州上学,但你在西安上学,于是你想着吧这个旧的台式机给你表顺丰寄过去。

假如你的台式机有8kg,但是顺分规定说一次只能寄3公斤(假如),此时虽然不能把整个电脑都寄过去,但是你可以先把电脑拆分一下,显示器、主机啥的拆开,只要拆成3kg、3kg、2kg的就行,打成三个包,此时就可以寄出去了,你表弟收到快递后就自己再将电脑组装起来就行。

这里就用到了分片的思想,顺丰就是数据链路层,你和你表弟就是网络层。拆电脑的是你,组装电脑的是你表弟,不能说顺丰给你表弟寄过去后还附带着把电脑也帮忙组装一下,所以进行数据分片的是网络层,分片发出去后组装也是由对端的网络层组装。数据链路层只负责运就行。

注意,网络层是无法决定自己能发总量为多大的报文的。就像你无法决定你的台式机有多重一样,能决定的是生产台式机的厂商。网络层完整数据报的大小完全取决于传输层数据段的大小。

我前面讲TCP的博客中,滑动窗口中的数据为什么要分多份来发,也是和这里的MTU有关系的,后面再细说。

网络层收到传输层的数据段后,网络层如果能交给数据链路层就交,交不了就要分片后再发。

那么分片是啥呢,就是将一个比较大的IP报文拆分成多个小的分片,能够满足MTU的报文。
在这里插入图片描述

2500大于1500,所以要进行分片:
在这里插入图片描述

分片的行为是网络层来做的,组装分片的行为也必须由对方网络层来做:

在这里插入图片描述

为什么要组装呢?
因为发送方网络层接收到的是一个完整的传输层报文,接收方在网络层向上交付的时候也必须是一个完整的报文,IP分片和组装的行为,上层是不知道也不关心的。

那么如何做到分片呢?
就是用报头中第二行的字段。
在这里插入图片描述

16位标识

在这里插入图片描述
16位标识就相当于是IP报文的序号。用来区分不同的IP报文。

像TCP报头中的序号一样。

3位标志

在这里插入图片描述

3位标志字段:
第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到).

第二位置为1表示禁止分片, 意思就是如果数据报中该位置为1,若数据报大小小于MTU就正常发,但若大于MTU,IP模块就会丢弃这个数据报。 这个可以用来查看当前最大数据报的大小。

第三位表示"更多分片",表示的意思是后续是否还有分片,假如一个完整的报文分成了4个分片,那么前三个分片该位就是1,第四个分片该位就是0。

13位片偏移

在这里插入图片描述

表示当前分片起始位置相对于完整报文起始位置的偏移量。

比如说一个1500字节的报文,如果被分成了三个500字节的分片,那么第一个分片该字段值就是0,第二个就是500,第三个就是1000:
在这里插入图片描述

注意,分片的行为不是主流行为,正常情况下能不分片就不要分片,整个协议栈从上到下都是要避免分片的。

说一说接收方组装分片时要考虑的方面:

  1. 能够识别不同的报文
  2. 识别报文是分片
  3. 识别哪些是开始的分片,哪些是中间的,哪些是结尾的
  4. 识别是否有分片丢失

第一个问题,通过16位标识就能解决,不同报文标识不同,一个完整的网络层报文的所有16位标识相同。当识别出分片报文时就将标识相同的报文放在一起。注意,网络层不像传输层,没有缓冲区,接收到完整报文后就会立马向上交付,所以不存在报文的积压,也就不可能存在相同标识的完整报文,只会有相同报文的分片。

第二个问题:
如果是分片,更多分片标志位就是1,
如果是最后一个分片,更多分片就是0,但是13位片偏移一定不为0。
如果报文没有被分片,那这个报文更多分片为0,13位片偏移也为0。

第三个问题:
开始的分片,更多分片为1,片偏移为0。
中间的分片,更多分片为1,片偏移为1。
最后的分片,更多分片为0,片偏移非零。

第四个问题,得画图来说,假如一个3000字节的数据报被分成了1000、500、500、1000,那么这四个分片的报头中的更多分片位和片偏移如下图所示:
在这里插入图片描述

通过观察可以看到,当前分片的片偏移 + 当前分片中所占原始报文的大小 = 下一个报文的片偏移

所以同一个报文的分片分到一块后,再根据片偏移来进行升序排序,再结合 当前分片的片偏移 + 当前分片的大小 = 下一个报文的片偏移,扫描整个报文,如果不匹配那么就一定有丢失,如果成功计算到结尾就一定收取完整了。

所以根据这三个字段就能成功完成分片和组装。上图画的不够严谨,我来画一个更严谨一点的图,假如说MTU为1500,一个3000字节的IP报文:
在这里插入图片描述
也就是:
在这里插入图片描述

第一个分片:
在这里插入图片描述
第一个分片可以将原始报文的报头直接利用上,不过一点字段要改一改,比如说报文长度什么的。

第二个分片:
在这里插入图片描述
当前分片片偏移为上一个分片所占原始报文大小加上其片偏移,注意第一个分片中的报头就是原始报文的报头,所以也会算上,第一个分片也就占用了1500字节的原始报文。

注意此时分片还没有结束,第二个分片中定长报头是新的(必须要有,用来标定分片报文的属性),占用20字节,那么这个报文还剩下1480字节可用,也就是说加上第一个分片的1500字节,现在对于原始报文共分了2980字节,所以还剩下20字节的原始报文没有取走,所以还需要再分一次:
在这里插入图片描述

当前分片片偏移为上一个分片(中间的那个)所占原始报文大小加上其片偏移,上一个报文所占原始报文的大小为1480字节,所以当前分片的片偏移为2980。新的固定长度报头20字节,数据20字节,这样就完成了3次分片。

对端在组装的时候,就是用第一个完整的分片和后续分片的有效载荷进行拼接,就能得到原始的完整IP数据报。

分片的坏处是什么?
在网络层分片和组装的过程上层是不知道的,网络通信的时候丢包是有概率的,必须保证所有的分片都被对方接收到才有意义,而每个分片都有可能丢包,所以相对于不分片而言,分片增加了丢包的概率,当接收方少收了一个分片,网络层如果检验和对不上就会直接将报文丢弃。

此时如果上层是TCP还可以重传,但如果上层是UDP,那就会导致UDP更容易丢包。所以严重不推荐分片。

网络层分不分片不是网络层说了算,想要彻底解决问题需要在传输层解决,尽量让传输层单次发送的报文小一点,这一点我在后面讲数据链路层的时候再说。

ok,到这里IP协议的报头就讲完了,下面说说很重要的网段划分。

网段划分

网络分段的好处

讲IP先不直接说理论。先来讲个例子,更好理解。

其实我们生活中对于网段划分同类的思想是非常多的,比如说我们的学号,假如说是202404020523,简单分一下,2024代表你是哪一届的,04代表你是哪个学院的,02代表你是学院中的哪个专业,05代表你是这个专业的哪个班级,23代表你是班里面的第几号。

你在你们班和其他人的学号的区分可能就是最后面的两位,因为你们班中就二三十个人,用二三十个数就能区分出来这些人,再扩大一点,到你的年级,05能代表你是五班的学生,而相同的两位比如说08就代表一个八班的学生。再往上就不讲了,一个道理。

IP用的就是这样的方法,打个比方,前面几位定一个地区,比如说前8位代表国家,00000001代表美国(假如),如果一个报文源IP是以00000001开头的就是一个美国的报文,再给5位用来标志一个美国的州,假如说说得克萨斯州是10110,那么源IP以0000000110110开头的就是来自得克萨斯州的报文,再往下就不说了,一直到32位用完,具体到某一个主机就结束了。应该懂了吧。

IP由两部分,一部分为网络号,一部分为主机号。
先根据网络号确定区域,然后再根据后面的序号再一步缩小区域直到找到目标主机。这个标定地区是一个相对的概念,上面美国的这个例子,00000001代表美国,那么00000001就可以看做是网络号,标定了一块地区,0000000110110代表美国的得克萨斯州,那么0000000110110也可以看做是网络号,标定一块更小的区域。这里的地区也可以叫做网段,比如说得克萨斯州的网段。

那么网段划分就是指将一个大的IP地址段划分成多个小的IP地址段的过程。

我直接以公网IP来讲。
现在主流的还是IPV4,也就是说能标定 2 32 2^{32} 232个主机,也就是42亿多个主机,先不说够不够的问题,这个话题后续再来讨论。

IP地址不是杂乱无章的,每个国家的IP地址在开始的时候已经划分好了。

简单表述一下,假如说哈,32位中的前8位用来标定某一个国家,那么就能表示256个国家,假如说中国前8位就是00000011,美国前8位是00000001,等等国家及其前8位编号。(注意我说的是假如)

比如说这样:
在这里插入图片描述
某一个地区的报文发出去后,如果是国际之间的报文,就要经过国际间的路由器。

然后还剩下24位,剩下的24位,假如说我国,还可以再分省,再用5位来标定每个省,比如说00001就是北京,连起来前面的中国就是00000011 00001xxx xxxxxxxx xxxxxxxx。

然后,还剩下19位,再往下分某一个省中的市……,反正就是往下分,一直划分到某个主机。所以IP划分是有规律可循的,但是也并不像我这里这样。划分到一定程度后就会执行其自己的方案,可能是划分到省之后就执行自己省内的方案,还有比如说华北地区什么的。但是只要划分了之后就可以定位一台主机。比如说你在B站发一条评论,其中会带上你的IP,浙江、北京、山西,甚至还有澳大利亚的。

不同国家会根据其国家人口、经济、政治等来划分IP个数,看:
在这里插入图片描述

那么划分IP的工作是由谁来做的呢?
运营商。

就简单介绍到这,下面来详细说说。

看图:
在这里插入图片描述
图中的网络标识就是指网络号,主机标识就是指主机号。

图中一个路由器级联了两个网段(网段也可叫做子网),一个是192.168.128(点分十进制我就不讲了,前面博客中已经介绍过),一个是192.168.144,也就是两个网段的网络号是不一样的,网络号是标定网段的重要依据,同一个网段内部大家的标识都是一样的,就好比前面讲的例子中以00000011开头的IP就是中国网段内的主机,可以有很多的主机都是以00000011开头的。主机号在同一个网段中一定是不一样的。

某一个网段发一个报文,路由器会根据该报文的目的IP中的网络号来判断是否是其他一个网段的,是了就转发到其他网段中,不是就是转发给当前网段中的,比如说上图中下半部分的网段发一个目的IP网络号为上半部分网段的网络号的报文,那么就先将报文发给路由器,路由器自行判断是哪一个网段中的哪一个主机,然后就将报文发送给对应网段中的主机。可能是下半部分的网段中的10号主机发给上半部分网段中的10号主机。

所以:
不同子网,网络号一定不同,主机号可能相同。
相同子网,网络号一定相同,主机号一定不同。

为什么要分网络号和主机号?
和前面讲的学号一样。一个班是一个子网,同一个专业的所有班级是一个较大的子网,同一个院的又是一个更大的子网,同校的……,想要在学校里找一个人,只需要知道其学号,然后从头开始分析第几届、哪个院、哪个专业、哪个班、哪个人,定位非常简单。

网络就是同样的原理,在查找的过程中检索的IP值不断扩大,但是检索的范围不断缩小,直至定位到具体的主机。

再来举一个例子,假如计算机学院的张三捡到了一个钱包,钱包中有一个人的学生证,学生证上有这个的学号,但是奈何张三在学校里面熟人不多,不知道应该交给谁,只知道根据学号来分析并不是他们院的。此时如果学号只是一串单纯的数字,那么找一个人就会非常困难。

张三可以在学校门口一个一个挨着问,但这样效率就太低了。

但是如果学号有含义,张三就可以把这个人的学生证发到年级群里,此时计算机院的院学生会主席也有一个群,一个全校学生会主席的群,于是就将这个照片发到了学生会主席的群里,这个群中有全校的学生主席,里面自然有一个院的学生会主席知道这个学号是对应自己院的,假如说是经管院的,那么经管院的学生会主席就将这个照片发到了经管院的年级群里,经管院的李四一看这个学号是自己的,正好自己钱包也丢了,那么就会自己和张三联系。

第二种方式效率就非常高,对应到网络中,正好可以说一些专业术语,上面学生证的照片就是数据,张三就是发送方,经管的李四就是接收方,学生会主席就是路由器,各种群就是网段(每个院都有每个院的年级群,年级群之下还有班级群,还有宿舍群啥的,还有上面说的校学生会的群),校学生会的群就叫公网。这里的公网像前面国际与国际之间路由器构建起来的网络,如果是国家内部的话公网就是省/区域(人少的省就看作一个大区)之间路由器构建的网络。

每次转发报文就是排除的过程,如果有了区域,一次就能排除一大片,效率很高。

如何进行网络划分

老版本的ABCDE

过去曾经提出一种划分网络号和主机号的方案, 把所有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

这些划分是技术人员搞的,最初的时候并没有考虑数量因素,哪个国家想要哪一类的地址就直接申请,假如说美国申请50个A类的,再申请30个B类的,然后我们中国再申请30个A类的,40个B类的……

随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址;
例如, 申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机. A类地址的子网内的主机数更多,然而实际网络架设中, 不会存在一个子网内需要这么多IP的情况. 因此大量的IP地址都被浪费掉了.

针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):

新版本的CIDR
  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
  • 子网掩码也是一个32位的正整数. 通常用一串 “0” 来结尾;
  • 将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号;
  • 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;

可能初学者看不懂。你先记住子网掩码左边全是一,右边全是0。左边全1的用来获取IP的网络号,右边全0的用来获取IP的主机号。

我来举一个例子,就拿前面国家的例子来讲,前8位代表哪个国家,这里给一个前8位为1的子网掩码11111111 00000000 00000000 00000000,然后假如说一个报文的目的IP是00000011 01011011 00111111 01011101 ,这个IP按位与上子网掩码就得到00000011 00000000 00000000 00000000,那么前面的8位与出来的结果00000011就代表的是网络号,此时就可定位到一个国家。

所以将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号。

给不同的路由器配置上不同的前n位为1的子网掩码就可以获得某一个IP落在哪个范围。比如说前面国际的路由器就给一个前8位为1的子网掩码,IP&子网掩码之后得到的就是哪个国家。假如一个来自荷兰的报文要发到一个河南小伙的主机上,先让这个目的IP&国际版路由器的子网掩码,确定出来是中国,再给中国国际版路由器一个前13位为1的子网掩码(假设国家的前8位后面 + 5位来区分省),中国的国际路由器根据中间5位得到IP在哪个省,然后再把报文发到对应的省级路由器……就这样一直往下走。

因为不同的路由器一定要至少级联两个网络,每一个网络的网络号可能是不同的(国家与国家之间),而且网络号表示的范围也不一样(比如上面国家到省的过度),每个路由器都要给与自己直接连接的网络配置对应的子网掩码,国际的路由器不但要有国际子网掩码,还有要的传递给省级路由器的省级子网掩码。

那么现在应该能明白报文是咋转发了吧。

在这里插入图片描述

子网范围地址就是指子网掩码全零能够表示多少个数。像第一个例子中子网掩码最后8位为0,那么就能表示 2 8 2^8 28个数,也就是256个。第二个例子中子网掩码后4位为0,那就能表示 2 4 2^4 24个数,也就是16个。

可见,IP地址与子网掩码做与运算可以得到网络号, 主机号从全0到全1就是子网的地址范围;
IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68, 子网掩码的高24位是1,也就是255.255.255.0

特殊的IP地址
  • 将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;

  • 将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;

  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1,前面我手搓TCP、UDP服务器的时候也演示过了,这里就不说了。

在这里插入图片描述

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还没有普及;IPV6想要普及的话有点困难,涉及到os的底层,这种大变更并不像微信啥的晚上睡觉的时候就能自动更新完成。

私有IP地址和公网IP地址

前面所说的IP都是公网IP,还有一类IP叫做私有IP,就是为了解决公网IP不足的问题。

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址

  • 10.*,前8位是网络号,共16,777,216个地址
  • 172.16.到172.31.,前12位是网络号,共1,048,576个地址
  • 192.168.*,前16位是网络号,共65,536个地址

包含在这个范围中的, 都是私有IP, 其余的则称为全局IP(或公网IP),私有IP不能出现在公网IP中,出现了无法被识别。

私有IP专门用来组建私网,也还可以叫局域网。

我们平时用的都是私网,不太可能接触到公网,比如说我在我电脑上用ipconfig(Windows下)查看我电脑现在IP是多少:
在这里插入图片描述
10开头的,就是刚刚讲的第一种私有IP。

说一下默认网关是啥,网关可以理解为一个网络节点,它负责不同网段之间的通信。 一般情况下(家用网络环境 或 较小的网络环境),默认网关就是我们的路由器设备。我们的普通环境下的局域网是由路由器构建的,在入网的时候是路由器最先入网的,所以其IP地址就是当前局域网中的第一台主机,所以后面点分十进制的最后8位的值就是1。

再在我的xshell上用ifconfig(Linux下)看看:
在这里插入图片描述

也是第一种私有IP。我这里连接的是云服务器,私网给的是10开头的,这里也不是我能决定的,你也查查你电脑现在IP是多少。192开头的也非常常见。

所以我们现在直接接触到的根本就不是公网IP,直接接触的都是私有IP。私有网络的IP是局部的,可以在不同的子网中出现重复的私有IP,这样IP不足的问题也就解决了。

如图(先不要细看,简单过一眼就行):
在这里插入图片描述

把图中的广域网看成公网。

下面我框起来的都是私网:
在这里插入图片描述

可看到图中有运营商路由器和家用路由器。

我前面讲网络第一篇的时候说过我们能够上网是因为有运营商为我们进行网络架设的,像移动、联通、电信等。

如果我们想要在家里面能上网,首先就要有运营商在你家附近有网络覆盖。然后再联系运营商进行光纤入户,工作人员上门为你家安装调制解调器(俗称猫),还会给你家一个无线路由器:

在这里插入图片描述

再给你家开户,设置路由器的账号和密码,并认证你家路由器的账号和密码(注意这里的账号和密码不是平时用的WiFi账号和密码,而是运营商能够进行认证的),认证完毕后你可以对你家的路由器设置WiFi名称和密码,路由器天然的会构建局域网,然后这些工作做完就能上网了。

为什么我们平时用软件(微信、B站啥的)不用交费,而是月底的时候给运营商充话费?
因为网络的基础设施是运营商帮我们铺设的,他们前期需要做大量的工作,费时费力,想要上网就要给他们交钱,因为你想要进行网络通信就得必须经过他们所搞的基础设施,不可能绕过这些设施,所以运营商天生的就是中间人,我前面讲HTTPS的时候说过中间人攻击的例子,这里就不多说了。

所以我们平时想要上网就要交话费,欠费了网就断了,因为运营商可以对你的设备进行认证,如果说你的设备欠费,运营商收到了你的报文之后能够识别出你的账号,然后一查你账号欠费了就直接把你包丢了,你就没法上网了,一交钱就能上网还是TA能够识别你的账号,一识别就能知道你交钱了,然后就把你的包放过去了。

我们平时软件不用缴费,原因是要缴费的软件存活不了太长时间的,比如说刷一个视频一分钱,那你一早上躺被窝里猛猛刷,想想一早上就得花多少钱,老百姓是不愿意支付这些钱的。

甚至互联网公司还要给运营商交钱,因为他们会用到运营商架设的网络。至于互联网公司怎么挣钱我就不说了。

再来想想为什么我们平时无法访问Google、Facebook这样的外网?
还是因为运营商,你的报文一定会经过运营商,人家一看你的目的IP是国外的就直接给你包丢了,你也没啥办法。你应该知道有方法能实现,我就不细说了。

还有一个,想想为什么你欠费的时候不能给你家里人打电话,但是10086一定能打通。

WAN口IP 和 LAN口IP

再回头看看这张图:
在这里插入图片描述
把图中的广域网当成我前面讲的一整个省。可以看到路由器的IP有两个一个叫WAN口IP,一个叫LAN口IP。

一个路由器:

  1. 对内,分配自己构建的子网所有主机的IP。
  2. 对外,自己本身也是一个由别的路由器所构建子网中的一个主机。

所以这两点也就决定了路由器需要有两套IP地址:

  1. 对内,LAN口IP,也就是其维护的私网的IP,也是私网中的第一台主机的IP
  2. 对外,WAN口IP,自己所在的上级子网给自己分配的IP

比如说我这里框起来的家用路由器:
在这里插入图片描述

其所构建的子网就是其左侧的两个主机和它自身,并且这个红色框框起来的和前面的那个家庭路由器用的是同一个上级子网,也就是这个:
在这里插入图片描述

可以看到这个运营商路由器所构建的子网,其自身的LAN口IP就是10.1.1.1,然后上方的家庭路由器WAN口IP是10.1.1.2,下方家庭路由器的WAN口IP是10.1.1.3,这两个家庭路由器所连接的WAN口IP就是由运营商路由器所构建出来的子网。但是运营商的WAN口IP是122开头的,这个就是公网了,也就是说这个运营商路由器连接了公网,并且自身构建了一个私网。

只有公网IP才会真正占用前面所讲的IPV4的资源,私网的资源是可以在不同的子网中重复的,看图:
在这里插入图片描述
图中是两个家庭路由器所构建出来的子网,也是两个私网,都是192.168.1.201和192.168.1.200,重复的,所以很明显,私网可以重复。

前面第一篇讲过,同一个局域网中的主机是可以不需要经过路由器而直接通信的:
在这里插入图片描述

但是如果是不同局域网中的两台主机就要经过路由器来搞了,那么如何做到呢?比如说这里的两台主机通信:
在这里插入图片描述
假如说上面连接公网的是某公司的服务器,下载你用这台红框框起来的电脑来向服务器发送请求。但有个问题,一个是公网的IP,一个是私网的IP,是否能够将请求报文中的源IP给成192.168.1.201,然后目的IP给成122.77.241.3呢?

不行的,如果源IP一直是192.168.1.201这个数,虽然能发过去,但是返不回来,因为私网IP在公网当中无法识别。因为如果服务器响应的报文中目的IP给了192.168.1.201,公网当中是不存在这个IP的,所以路由器也就无法识别这个IP,那么怎么办呢?

私网中路由时需要做一件事情:

  • 将报文中的源IP替换成路由器的WAN口IP

每次经过一个运营商的私网路由器都要做这件事,注意是私网,公网路由不做。

这样整个过程就变成了这样:
在这里插入图片描述

客户端在请求的时候需要让源IP在不同的内网、不同层级的网络节点中转发,被替换的技术就是NAT,但是数据怎么从公网发回到私网,以现在的学习进度还无法讲解,得后面再说。但至少这里能发回到当前主机间接连接到的公网了。

前面说了虽然IPV6很难在世界推广,但是可以在局部推广,比如说强制让运营商在局域网中用IPV6,而且让某些公司的服务器采用IPV6协议,只有在进入公网的时候再将IPV6转成对应分配的IPv4的就行。我们虽然无法影响到国际上的公网,但是能够影响到我们国家中的私网。

路由

在复杂的网络结构中, 找出一条通往终点的路线。

IP能知道目的IP地址和源IP地址。但是TA不知道报文发出后向哪一个路由器发送,这个需要MAC地址来决定。
西游记应该都看过吧,唐僧应该都知道吧。就拿唐僧来说。

  唐僧从头到尾在别人问他从哪来到哪去时,他总是说的是“贫僧从东土大唐而来,到西天拜佛求经”。这一路上他就要干这个,源头到目的地永远不会改变,一直是东土大唐(源头)到西天(目的地)。
  假如唐僧是个路痴,每到一个地就得问一个人下一站往哪走。假设此时唐僧师徒四人在碧波潭已经把万圣龙王给端了,此时他问路人去西天要往哪走时,路人给他说往荆棘岭走,唐僧一行人就屁颠屁颠的往荆棘岭去,然后通关荆棘岭后又在荆棘岭问路人该去哪时,路人说去七绝山,然后四人又去七绝山了。

至此,就可以说说IP地址和MAC地址了。

这里唐僧身上有两套地址。
.
IP地址就是从头到尾一直不变的东土大唐 ==》西天,那么东土大唐就是源IP,西天就是目的IP。IP地址从头到尾一直不变。但是IP地址可以为唐僧从当前站到下一站往哪走提供方向。
.
MAC地址是会随着唐僧所在位置的变化而变化的,唐僧在碧波潭时,下一站要往荆棘岭走,此时的出发地是碧波潭,目的地是荆棘岭,那么这里的源MAC地址就是碧波潭,目的MAC地址就是荆棘岭。而当唐僧跑到荆棘岭后,下一站要往七绝山去,那么此时源MAC地址就是荆棘岭,目的MAC地址就是七绝山。每次的目的MAC地址都是受目的IP(西天)影响的,不能说唐僧要去西边,下一站的MAC地址跑到了东边的高老庄。

  • 唐僧在取经时,源IP和目的IP永不变。每次经过一个地方就相当于数据经过了一台路由器,问路人西天怎么走时路人会为唐僧回答下一站在哪,这个过程就叫做路由,那么路由的本质就是根据数据的目的地选择下一站去哪里。

MAC地址能够表示局域网中某一主机的唯一性。

IP地址在整个公网中是唯一的。

能听出来区别不,MAC的唯一性是局部的,而IP的唯一是全局的。

MAC是在数据链路层的,IP是在网络层的,但其实在局域网中也可以用IP来标定一个唯一主机,而实际上并没有这么做。

虽然IP地址在局域网内是唯一的,但它们并不是为设备提供唯一标识的最佳选择。这是因为IP地址通常是由网络管理员手动分配或通过DHCP(动态主机配置协议)自动分配的,它们可能会因为各种原因(如设备移动、网络重新配置等)而发生变化。因此,IP地址虽然可以用于识别设备,但并不是设备固有的、不可更改的唯一标识。

相比之下,MAC地址(媒体访问控制地址)是网络设备在物理层上的唯一标识。它是由设备制造商在设备生产过程中直接烧录到网卡上的,全球唯一且不可更改。这意味着,无论设备在网络中的位置如何变化,其MAC地址都不会改变。因此,MAC地址更适合用于在局域网中唯一标识设备。

此外,MAC地址在网络通信中也起到了关键作用。当一台计算机要发送数据到另一台计算机时,它首先需要知道目标设备的MAC地址,然后将数据封装成数据帧,并通过物理介质(如以太网)发送到目标设备的MAC地址。接收方根据目标MAC地址来接收和处理数据帧。因此,MAC地址在局域网中的数据传输和通信过程中是不可或缺的。

报文的转发

路由的过程, 就是这样一跳一跳(Hop by Hop) “问路” 的过程.
所谓 “一跳” 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间.

在这里插入图片描述
IP数据包的传输过程也和问路一样.

  • 当IP数据报, 到达路由器时, 路由器会先查看目的IP;
  • 路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
  • 依次反复, 一直到达目标IP地址;

路由分类

唐僧问路的时候可能出现三种情况:

  1. 路人知道,直接给唐僧说下一站去哪
  2. 路人不知道但是知道谁知道,让唐僧去问知道的人去
  3. 路人不知道但是也不知道谁知道

在网络中路由器可不敢出现第三种情况,不然报文发给一个路由器后就没法往下走了。

路由器其实可以分三种:

  1. 知道下一站怎么走的,会直接将报文发送到下一跳网络的路由器。最典型的就是公网路由,直接用子网掩码和目的IP进行按位与,得到网络号,公网路由出来就去找对应的网段去。
  2. 不知道下一站怎么走的,会将报文转到默认路由,比如说下面这张图:
    在这里插入图片描述
    主机A发送一个报文,目的IP是公网的IP,家用路由器是不认识的,所以就会将这个公网的IP发送到当前子网的默认路由器 ⇒ 运营路由器处,如果运营路由器也不认识,那就再往上传。直到传到公网的路由器手中。
  3. 入口路由器,就是已经找到了目的网络,下一步就是找到网络中的那个主机。比如说唐僧已经到东土大唐了,也就是到了目的的网络了,此时再问路人就不会再说东土大唐在哪里了,而是直接问路人灵山怎么走。所以到了最后一个路由器的时候,报文问的是TA想要到的主机怎么走,因为报文已经到了其想要去的子网当中,直接去这个子网中找主机就可以了,而不是问目的网络怎么走。

那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表。
路由表可以使用route命令查看:
在这里插入图片描述
路由表的Destination是目的网络地址,Gateway是下一跳地址,Genmask是子网掩码,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。

default就是指默认路由,也就是路由器。

route加上 -n选项就是能显示成数字的就显示成数字:

在这里插入图片描述

这台主机有两个网络接口,一个网络接口连到10.0.24.0/22网络,另一个网络接口连到169.254.0.0/16网络;

【例1】如果要发送的数据包的目的地址是169.254.235.3。
先和第二行的子网掩码按位与,得到169.254.234.0和10.0.24不是一个网络号,跳过 ⇒ 再跟第三行的子网掩码做与运算得到169.254.0.0,正是第三行的目的网络地址,因此从eth0接口发送出去 ⇒ 由于169.254.0.0/16正是与eth0接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器发;

【例2】如果要发送的数据包的目的地址是202.10.1.2
依次和路由表前几项进行对比, 发现都不匹配 ⇒ 按缺省路由条目, 从eth0接口发出去, 发往10.0.24.1路由器 ⇒ 由10.0.24.1路由器根据它的路由表决定下一跳地址。

所以整个流程是先查目标网络,再查目标主机,所以跨网络的通信全程的协议栈就是这样走的:
在这里插入图片描述

网络层只是一个打工的,传输层提供端对端的策略服务,网络层提供数据转发功能,就使得TCP/IP协议可靠的将数据从A主机发送到B主机。

但IP并没有解决设备转发的具体功能,IP提供的是转发的策略,提供IP、子网划分、路由查找与路由算法的策略,帮助报文的转发。

网络层就讲到这,下一篇讲数据链路层,数据链路层最基本的服务是将当前节点网络层来的数据可靠的传输到相邻节点的网络层,本篇中一些遗留问题也是到下一篇的时候再讲。

到此结束。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

先搞面包再谈爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值