网络层协议

2023-12-18 09:50:17

目录

IP协议

IP协议介绍

IP协议的格式

4位首部长度

16位总长度

8位协议

4位版本

8位生存时间

8位服务器类型

16位首部校验和

IP报文分片

IP分片

16位标识

3位标志

13位片偏移

案例

IP报文的组装

IP如何定位主机

网段划分基础理解

案例

网段划分理解

特殊IP地址

公有IP和私有IP

NAT技术

路由


IP协议

IP协议介绍

网络层协议也就是我们说的IP协议,我们知道每一层协议都是用来解决问题的,而TCP协议是用来解决数据如何可靠从一台主机到另一台主机的,那么IP协议是解决什么问题的呢?

由于网络中发送数据,一定不是之间从这台主机到另一台主机的,而是从一个一个路由器上一跳一跳走的,而IP协议就是解决路径选择的问题的,那么有那么多路由器,我们应该选则去那一台路由器呢?这个就是由IP协议来解决!

我们不论学习哪一个协议,我们都是需要解决两个问题的:

1.如何封装和解包

2.如何向上交付

IP协议也是需要解决这两个问题的,下面我们会说IP协议的格式,然后回答这两个问题!

IP协议的格式

我们先回答上面的两个问题:如何封装解包,以及如何向上交付!

4位首部长度

IP协议里面也有4位首部长度,IP协议的报头首先是定长的 20 字节,但是还有一个选项,选项也是属于IP报头的一部分。 那么要如何将报头与有效载荷分离呢?先说4位首部长度是什么? 4位首部长度其中就是4个比特位,4个比特位能表示的大小就是 0000 -> 1111 那么也就是4位首部长度最大可以表示15,但是IP协议的基本大小就是20,也就是超过了15,那么4位首部长度怎么表示报头的长度呢?其实4位首部长度是有单位的,而单位就是(4 字节)! 那么我们就可以计算一下,IP协议的基本长度是20字节,那么也就是:x * 4 = 20; x = 5; 也就是说4位首部长度的基本大小是 0101。

那么我们知道了4位首部长度,那么我们怎么才能解包呢? 我们先读取20字节,然后读取到4位首部长度,然后用4位首部长度乘4,然后在读取这个结果减20的长度,也就是将选项全部读取出来,将选项全部读取出来就剩下有效载荷了。

16位总长度

但是我们知道有效载荷是多少字节吗?知道! IP协议里面的16位总长度,表示的是整个报文的大小,那么我们只需要将16位总长度减去IP协议的报头,就是有效载荷的大小了,我们只需要将这有效载荷读取出来即可,然后将有效载荷交付给上层即可!

8位协议

那么我们知道交付给哪一个上层吗?其实也是知道的! IP协议的上层我们经常使用的也就是那几个,而8位协议里面填的就是需要交付给哪一个上层,所以我们只需要读取到8位协议,然后将有效载荷交付给8位协议里面填的协议即可,我们就交付完成了!

上面的三个IP协议的报头已经帮我们解决了如何封装解包,以及向上交付的问题了下面我们看一下其他的协议!

4位版本

IP其实也是有版本的,不过我们一直使用的都是IPv4,不过现在我们也有IPv6的,但是这个里面就是填IPv4即可。

8位生存时间

因为IP协议是需要解决路径寻找到问题的,那么有没有可能会有一个报文一直在路劲里面循环呢?有没有可能路由器的路劲选则算法出现问题了,所以导致数据报无法到达,然后一直游离在网络中呢? 如果是这样的话,也就是数据报因为集线器的存在一直可以在网络中存在,那么是不是导致网络中可能会有大量的游离的报文呢? 所以那么我们要不要给一个数据报设置一个在网络中生存的时间呢?需要!8位生存时间表示的就是一个报文在网络中可以经过多少个路由器!

一般情况下8位生存时间都是64,而64表示的是每经过一个路由器就进行减减操作,如果这个为0,那么该报文将不会被转发了!

8位服务器类型

8位服务类型里面是什么呢?

8位服务类型里面有三个是优先权字段,但是以及弃用了。

还有4位是TOS字段,分别有: 最小延迟 最大吞吐量 最高可靠 最小成本 这4个字段是不能一起出现,他们是互相冲突的。

还有一个是一位保留,这一位还没有想好怎么使用,所以就保留!

16位首部校验和

16位首部校验和就是用来检验IP报头是否有损坏的,如果有损坏的话就丢弃!

关于IP报头的协议里面还有第二行的三个字段没有说,但是我们在说这三个字段的时候,我们需要说一下IP报文的分片,因为这三个字段与IP报文的分片有关!

IP报文分片

IP分片

首先说一下什么是分片,以及为什么要进行分片,分片像TCP协议里面的捎带应答,或者确认应答一样吗?是不是分片是在每一个报文之间基本都会干的?建议分片吗?

下面我们来回答上面的这些问题!

什么是分片: 因为TCP将有效载荷封装好后,然后将数据段交付给IP协议,此时IP协议就会进行当前层的封装,当封装好后,将这一整个IP报文分成若干个符合条件的IP报文,也就是将有效载荷分为若个部分,然后将这若干部分都加上IP报头!

为什么需要分片呢: 我们已经知道分片是什么了,但是为什么需要分片呢? 其实这个就和下层有关,由于最后的发送一定不是IP层发送的,因为IP也只是一个协议,IP也是需要将数据交付给数据链路层的,而数据链路层一次只能发送1500字节的数据,但是这个值是可以调节的,所以就需要分片,也就是IP交给下一层的数据不能超过1500字节! 这里就有问题了,为什么是需要IP协议分片呢?数据链路层自己不能分片吗?可以!但是由IP来分片是更好的,我们可以这样想,现在你需要发一个快递,但是这个快递太大了,物流公司不能一次发送这么大的快递,那么物流公司会帮你将这个快递拆开吗?并不会,物流公司一定是让你自己拆开,然后他们来发送,因为如果拆坏了谁来弄?到时候等快递到了又谁来组装?所以数据链路层也一样,他们知识定制规则,如果你想要使用这个那么就需要你来遵守,所以是IP层自己来拆封,那么在这个拆封的过程中,上层TCP是知道吗?并不知道,所以在IP层上面他们看来是没有区别的!

分片式主流吗: 这里就是我们要回答的下一个问题,也就是IP报文的分片像TCP的那些策略一样吗?也就是分片是经常的吗? 并不是,这里虽然我们在说分片,但是实际上分片并不是主流,而不分片才是主流!

建议分片吗: 那么我们建议分片吗?其实是并不建议的,为什么? 我们知道如果IP将一个报文分成了十个,如果每一个报文的丢包率位 %0.1,那么分成十个后,着一整个报文的丢包率就是%1了,因为将一个报文分成若干个,如果丢了一个,那么在TCP看来就都是丢包,所以这个报文就需要丢弃,所以其实是并不建议分片的,因为分片会增加丢包的概率!

那么下面我们就来看剩下的IP报头!

16位标识

当一IP分片后,我们怎么来区分,分片后的IP报文是一起的呢?也就是这是一整个报文分片的呢? 16位标识可以用来判断是否是一起的。 如果是同一个报文的话,那么IP协议里面的16位标识是相同的,如果不是同一个报文的话,那么16位标识就是各部相同的!

所以当我们收到一批IP报文后,就可以将16位标识相同的放到一起,也就是将同一个报文的IP报文放到一起,然后到后面合并的时候使用!

3位标志

3位标志里面是什么呢? 一位是保留,还没有想好怎么使用。 一位是禁止分片,如果设置了该字段,那么就不能将该报文分片。 一位是跟多分片,如果设置了该字段,表示该IP报文后面还有更多的分片。

13位片偏移

13位片偏移是什么呢?我们说了,如果一个报文分片了,那么我们怎么组装呢?使用13位片偏移就可以知道它是第几个报文! 如果一个报文分片了,那么首先分片后第一个报文的片偏移就是0,下一个报文的片偏移就是前一个报文的片偏移加上上一个报文的长度!后面我们会将这几个字段一起说,就更好理解!

案例

现在,应用层将数据交付给TCP层后,TCP封装后交付给IP层,当IP封装后,一共3000字节!由于3000字节太大,所以需要拆分为小于等于1500字节的数据报,然后交付给下一层!

现在交付给IP层后,IP报头20字节,有效载荷2800字节!那么需要如何拆分呢? 在拆分之前,我们需要想清楚,我们拆封后,是需要每一个有效载荷都需要一个IP报头,还是说只需要一个IP报头就足够了?其实是每一个有效载荷都需要一个IP报头!

首先当IP层封装好后,发现总大小超出了发送的最大长度,那么就开始拆分:

上面总大小为3000字节,所以需要拆分,第一次就直接拆分1500字节也就是第一次拆分,所以还剩下1500字节。 那么剩下的1500字节可以直接添加IP报头,然后交给下一层吗?不可以,因为这是有效载荷是1500字节,IP报头还有至少20字节,所以再加上IP协议的报头20字节的话,那么就超出了1500字节,所以是不可以直接添加IP报头的,所以还需要继续拆分。 将剩下的1500字节拿1480字节,然后添加IP报头,刚好1500字节,这又是一次拆封。 最后还剩下20字节,然后添加IP报头,将最后的40字节发送即可。

那么那三个IP报头怎么填呢?

首先是这三个报文时一个报文拆分的,所以16位标识是相同的,这里我们假设位1234,所以这三个都是相同的。

那么第一个拆分的报文,因为该报文后面还有更多的报文,所以更多报文的标志位为1,但是因为这个报文是第一个报文,所以它的片偏移是0。

第二个一样,因为后面还有报文,所以更多报文的标识位为1,而片偏移就是前面的片偏移加上前面报文的大小,也就是1500。

第三个拆分因为后面没有更多的报文了,所以更多报文的标志位0,但是片偏移不为0,计算就知道了。

那么这三个标记位也说清楚了。

下面我们又有问题了,因为TCP交付给IP的时候,是一整个,那么我们可以将拆分后的直接交付给TCP吗?不可以,因为TCP交给IP的是一整个,如果IP擅自拆分,那么TCP怎么知道发送过来的数据到底是什么?所以IP还需要将拆分后的报文在组装起来,那么如何组装又是一个问题!

IP报文的组装

要想知道IP报文的组装,那么我们就需要分清楚一些问题:

1.我们知道那些报文是一起的吗? 2.那些报文是第一个,那些报文时最后一个,也就是报文的顺序? 3.我们知道报文收全了吗?

我们现在如果解决了这三个问题,那么IP报文的组装那么也就没有问题了,那么这三个问题我们知道吗?

我们知道IP报文是一起的吗? 其实是知道的,在IP协议里面的16位标识,该字段就是用来标识一整个报文的,如果这些报文是一整个报文拆分的,那么这些报文里面的16位标识就是相同的,所以我们可以将16位标识相同的报文放到一起,这样我们就可以将同一批的报文放到一起,以便于后续的组装!

第二个问题,我们知道报文收到后的顺序吗》如果我们不知道的话,那么如何组装? 其实这个我们也是知道的! 第一个报文:我们怎么区分是第一个报文呢?其实第一个报文就是更多分片为 1,但是片偏移为 0。 最后一个报文:最后一个报文就是更多分片为 0,但是片偏移不为 0。 那么中间的报文我们知道顺序吗?我们知道IP报头协议里面有一个13位片偏移,而这个字段就是排序号后就是报文的顺序,但是因为又可能报文会丢失,所以在排序后还需要计算,如果有不符合的,那么说明报文丢失,所以TCP就需要重传!

上面我们就将IP报头里面的内容全部谈完了,但是我们还是有很多问题!

IP如何定位主机

网段划分基础理解

我们知道IP层是解决什么问题的,IP就是用来定位主机的,那么如何定位主机呢?IP地址是怎么划分的?

首先我们想要回答这个问题,我们先从公网IP的角度出发:

这是地球,由于我们使用的是 IPv4网络,所以以哦那个有32位,上面是各国国家标识,由于IP也是有限的,所以IP地址也就是资源,既然是资源,那么需不需要划分呢?需要的,那么就需要划分,那么如何划分呢?

首先可以将头部8位比特位分配:

就这样,将前8位比特位划分,然后交给各个国家,所以各个国家的前8位就是不同的,那么此时如果有一个报文需要转给前8位是 1000 0000 的主机,那么我们就可以根据这前8位知道是转给哪一个国家的,然后交给这个国家,此时还有后续的定位就需要让这个国家的路由器来完成了。

但是只分配国家是不够的,因为国家下面还有各个省份,省份下面还有各个区,区下面还有市,市下面还有县,等等...

所以还是需要继续划分的。

当这样划分下去,前面用来定位国家,省份,区等的字段就越来越多,而后面剩余的也就越来越少,所以到最后就可以定位到某一台主机!

而我们把前面定位的称为”网络号“,后面的称为”主机号“。 所以IP地址其实是分为两部分的: 网络号:就是保证互联的两个网段有不同的标志 主机号:在同一个网段中,可以区分不同主机的标识

案例

下面我们可以举一个例子来理解一下这个IP定位:

现在你在一个学校,你在去食堂的路上的时候,你捡到了一个钱包,钱包里面有它的学生证,但是你并不认识这个人,现在你就将这个学生证拍了一张照片发到了你们班级群里面,你@了一下你们班长。 你们班长看到这个学生证的时候,你们班长看到这个学生证并不是我们自己班里面的,所以它就只能将这张照片交给了你们学院,假设你们学院是教育的,然后你们班长也@了一下你们学院的院学生会主席,院学生会主席看到了这个学号以后,发现不是自己学院的,发现是医学院的,所以你们院的学生会主席发送到了学生会主席的群聊里面,同时@了一下医学院的学生会主席。 医学院的学生会主席看到后,发现是临床的,所以就给学院的群聊里面讲这一张照片发送出去,并且@了一下他们的班长。 最后临床的班长看到是自己班级里面的学生就让该学生去联系对应的人去取钱包。

所以这里的照片就是数据,而学号就是IP地址,因为学号也是和IP一样分的,所以每一个学院的前面的几位数字是不同的,相同学院的学号,学院号是相同的,但是不同的专业专业号就是不同的,而相同的专业,不同的班级,专业号是相同的,但是班级不同,而每个班的班长一定可以认识班级里面的学生,这样就可以联系到对应的学生,也就是将数据发送给对应的主机,而这个也就是IP定位的理解!

上面其实就可以将IP的定位解释清楚了,下面我们看一下实际的网段划分:

网段划分理解

其实上面我们说的网段划分基本就是上面的理解,但是我们不知道实际上是怎么做的,所以下面我们看一下实际上是怎么做的!

虽然下面是一种做法,但是我们目前并不是使用这种,而我们实际上使用的公网与私网,因为下面的是将IP地址的利用率增加了,但是并没有增加IP地址的个数,而如果想要实际的增加IP地址其实是有两种方案的: 1.动态分配IP地址 2.NAT技术 3.IPv6解决 下面我们先说一下我们的网段划分:

在上面的网络划分中,实际上就是将网络号相同的主机放到一起,这就是子网,而想要到子网中添加一台主机,那么就需要网络号是相同的,且后面的主机号是唯一的,如果重复的话,那么就是不可以的!

所以通过合理的设置网络号和主机号就可以保证相连的网络中,主机号都是不同的。

但是如果这样手动的分配IP地址太麻烦了,那么怎么办呢? 其实之前有一种技术 DHCP 技术,可以自动的给网络中的主机分配IP地址。这样就减少了手动管理的麻烦!

其实在过去提出了一种方案,将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

但是由于A类网络后面的主机号太多,没有局域网可以有这么多主机,所以A类会有大量的浪费,所以这里又引入了一个新的解决方案:CIDR 也就是引入一个子网掩码,来区分网络号还是主机号。

网络号就是IP地址和子网掩码做与运算就可以得到网络号!

特殊IP地址

  • 如果主机号全为 0:表示的是这个网段的网络号

  • 如果主机号全为 1:表示的是广播地址,也就是给这个网段里面的所有主机都发送数据报

  • 127.* :表示的是本地环回,用于本主机测试,通常是 127.0.0.1

公有IP和私有IP

前面我们说的解决方法是使IP的利用率增加了,但是并没有实际的增加IP地址,下面我们分公有IP和私有IP来解决,32位IP地址,一共有42亿多,但是由于现在的入网设备越来越多,所以实际上的IP地址是不够使用的,所以就决定将2000多万个IP用来组建私有IP,而私有IP是可以在每个局域网中出现的,所以这样的话,就解决了IP地址不足的问题了,如果当一个地方2000多万的私有IP不够使用,那么就可以在下放一个公有IP即可!

假设现在我们需要访问一下 122.77.241.3 这一台服务器,而这一台服务器是公网IP,所以是可以直接访问的,那么现在 192.168.1.200 想要访问这一台服务器!

现在我们需要怎么访问呢?

192.168.1.200 这台主机是私有IP,而私有IP是不能出现在公网上的,这台主机访问 122.77.241.3 ,根据IP地址的路径选则的话,首先需要去访问 192.168.1.1 这台路由器,而这台路由器级联两个网段,而这一台路由器也进行路径选则,因为目的IP是一直不变的,所以每一次都找的是同一台主机,然后这台路由器进行路径选则后,将报文交给了 10.1.1.1 这一台运营商路由器,而它知道想要转交的数据应该交给那一台服务器,所以就将数据交给了 122.77.241.3 。

虽然数据交给了122.77.241.3 台服务器,但是数据交给他是目的吗?并不是,我们需要将数据交给这台服务器上的一个进程,然后让该进程处理我们的请求,返回对应的数据,既然需要返回对应的数据,那么如何返回呢?我们需要怎么回去呢?

因为如果直接以 122.77.241.3 这台主机的IP来看的话,这台主机的IP是私有的,首先是私有IP不可以出现在公网里面,还有就是因为私有IP并不是唯一的,而是很多的网段里面可能会出现重复的私有IP,所以如果直接使用私有IP那么是不能将数据返回的,那么怎么办呢?

NAT技术

因为服务器想要将数据给发起请求的私有IP的主机,但是似有IP并不是唯一的,所以无法将数据给它,如果直接将报文转给服务器的话,那么就是不可以的!

因为实际上转发数据报是需要路由器转发的,那么路由器想要将一个报文从一个子网转发到另一个子网是不是路由器就需要级联两个子网呢?是的,路由器是级联两个子网的! 而路由器对于自己的网段里面的那个IP称为:LAN口 路由器级联上一级网络的哪一个IP是:WAN口

所以我们需要怎么做呢? 在 192.168.1.200 台主机转给 122.77.241.3 台服务器的时候,首先进行IP路径选则,然后知道了应该将报文发给下一跳哪一个路由器,但是当转发的时候,并不是直接转发,而是将IP报文里面的源端口号修改,修改为自己的WAN口IP,该路由器转发给下一个路由器的时候,也是这样做,直到转发到目标服务器,此时目标服务器就认为是 122.77.241.4 这个运营商服务器发起的请求,所以此时当服务器响应的时候就将数据交给122.77.241.4 台运营商服务器,而这一台服务器也会将之前进行NAT的IP的对应的路由器,将数据转发给对应的路由器,这样就可以将数据返回了。

路由

那么我们之前也说IP报文进行路径选则,IP决定将该报文从当前节点发送到下一个节点,而这个就叫做路由, 路由的过程就是将数据报一跳一跳的送到下一个路由器,直到送到目标主机!

路由的过程就是将数据报一跳一跳的送到下一个路由器,直到送到目标主机!

当一个报文到一个路由器的时候,首先该路由器看将报文发给主机,还是将报文发送给下一个路由器,直到这样送到目标主机!

现在讲一个故事: 现在你需要去哈佛大学,你到了对应的城市,但是你还是不直到走到那里,所以现在你看到一个路人,你去问这个路人,哈佛大学在哪里?那么这个人会有两个回答,第一个就是他直到去那里,所以他直接就给你说怎么怎么走! 第二他不知道去那里,所以他就和你说,你去问别人吧,然后给你路上指了一个人,说这个人经常在这块区域转,所以他直到。

而此时你就是这个报文,而路人就是路由器,当路人直到去哪的时候,就是找到了对应的主机,所以直到报文需要发送到那里,如果不知道就是将报文转发到下一个路由器!

而如果不知道的话,就会转给默认的路由器!

文章来源:https://blog.csdn.net/m0_73455775/article/details/135054327
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。