• Linux——IP协议1


    目录

    协议头格式

    如何封装和解包

    如何交付(分用)

    报头每一个字段

    分片是怎么做到的


     

            应用层解决的是数据使用的问题。

            在传输层,网络层,数据链路层:解决的是网络通信的细节,将数据可靠的从A主机跨网络发送到B主机。

            可靠性由传输层决定,从主机A送到主机B由网络层决定。

            IP协议主要是提供一种能力,将数据从A主机送到B主机的能力。有这种能力,一定能把数据送给对方吗?不能,有能力是指有很大概率能做成,而不是一定能做成。

             主机: 配有IP地址, 但是不进行路由控制的设备;

            路由器: 即配有IP地址, 又能进行路由控制;

            节点: 主机和路由器的统称;

    协议头格式

    数据部分有TCP数据段

    如何封装和解包

             IP协议也是固定长度的报文,前20个字节就是固定的,也可携带选项。读取前20个字节,就能读取到报头的相关属性了,先读取前20字节,再读取4位首部长度,用首部长度减去20字节,得到的就是选项。如果没有选项,4位首部长度就是5(0101).

            IP采用的是定长报头和子描述字段。

    如何交付(分用)

             8位协议表示有效载荷部分表示是UDP还是TCP,根据8位协议决定交给TCP还是UDP。

    报头每一个字段

             4位版本:就是IPV4,指定IP协议的版本, 对于IPv4来说, 就是4

            IPV6和IPV4差别:IPV4是4字节,32个比特位来表示IP地址,IPV6用128位比特位表示IP地址。但IPV6和IPV4是不兼容的。现在所有的计算机用的都是IPV4。

            4位首部长度:IP地址表示报头长度用4个比特位表示,即十进制下0-15,4位首部长度有自己的单位,基本单位是4字节,即整个报文的宽度0-32比特位,假设4位首部长度是4,整个报文长度就是4*x,即最终能表示0-60的数字。

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

             16位总长度:IP数据报整体占多少个字节,有效载荷=16位总长度-4位首部长度*4

            生存时间:当一个报文进行转发的时候,可能会由于路由器问题,导致报文在路由器里长时间转发,经过了大量路由器,为了防止出现环路转发的情况,给每个报文设置了生存时间。  生存时间本质是一个计数器,每转发一次,计数器--,当生存时间为0时,便不在路由器中转发,直接丢弃。

            16位首部校验和:如果首部校验失败,报文就被直接丢弃,我们不用担心报文被丢弃,发送方主机会重传。

            32位源IP:数据包从哪来

            32位目的IP:数据包到哪去。

    IP报文的形式和TCP报文非常类似,因此称为TCP/IP协议。

             链路层由于物理特征的原因,一般无法转发太大的数据,链路层有一次可以转发到网络的报文大小的限制。一般是1500字节,一般称为MTU(最大传输单元),若网络层要向下交付2500字节数据,网络层就需要做一件事情:“数据分片。”

            分片之后,又由谁来组装? 谁分片,谁组装(对端网络层),谁污染,谁治理。

            分片是将一个较大的IP报文,分割成多个较小的 ,满足条件的报文,分片的行为是网络层大的,同样组装的行为也必须由对方的网络层做。

            对方为什么要组装?因为对方给自己的网络层是一个完整的TCP报文,接收方在网络层向上交付也必须是一个完整的报文。IP分片和组装的行为,TCP是不知道,不关心的。

    分片是怎么做到的

     

             16位标识是IP报文的序号,可根据这个序号区分报文,唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的

            3位标志:第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话,最后一个分片置为0, 其他是1. 类似于一个结束标记,一般情况下如果没有被分片,更多分片标志位的最后一位是0。

             13位分片偏移:是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了)。

            报文长度是1500字节,分成三份,第一个片偏移量0,第二个500,第三个1000.

            更多分片是1代表该分片后面还有分片:如下面这张图里更多分片是1,1,0。

            虽然有分片,但分片行为不是主流,能一次交付就尽量一次交付。

            接收方若要组装,就要识别出报文和报文的不同(通过16位标识区分,不同报文标识不同,相同报文的分片,标识是相同的。)

            还要能识别该报文是否被分片了。如果3位标志的第三位“更多分片”标志位是1,就代表它被分片。

            如果“我”就是最后一个分片,那么我的“更多分片”标志位就是0。13位片偏移一定不为0,因为“我”前面一定有报文。

            即一个报文没被分片,更多分片标志位是0,而且13位片偏移也是0。

            判断是否被分片的伪代码

            当我们收到一批报文时,先尽可能的讲报文的分片,区分出来,并放在一起。

            又识别出哪些分片是开始,哪些分片是中间,哪些分片是结尾呢?

            区分开始:只要是分片的,更多分片是1,片偏移是0。

            区分结尾:更多分片为0,片偏移不是0,中间报文可能会有多个。

            区分中间:更多分片是1,片偏移不是0.

            我们如何保证把分片收全了呢?如果在组装过程中,任何一个分片丢失,也要识别出来,那如何识别呢?

             ID:1234

             根据偏移量来进行升序排序,结合偏移量+自身大小=下一个报文的偏移量大小,来扫描整个报文,如果不匹配,中间一定会有丢失的,如果成功计算到结尾,就一定收取完整了。

             根据3位标志和13位片偏移,可以进行组装。

            在组装过程中,如果某报文丢了,偏移量就会对不上,这样就能找到丢失的片段。

            分片之前,一定是一个独立的IP报文。分片之后,是每一个分片都要有IP报头,还是直接进行分片而且报头跟着第一个分片就行。

             

             答案是每一个分片都要有IP报头,这样才能进行之后的组装,因为如果没有IP报头,接收方无法接收。

            而上图中的3000字节,,MTU是1500,如何分呢?报文标识是1234

    第一个报文

             由于进行了分片,新报文的报头也要变,如16为总长度会变小,由3000变为1500.

            对于剩下的1500字节的报文,又该如何发送?

            若直接加报头,则整个报文会变为1520字节

    因此我们要继续拆分,拆个1480出来,再添加20字节的IP报头。

    之后再对剩余的20字节做同样处理。该偏移量是原始报文的偏移量1500+1480

     

             分片我们严重不推荐,分片坏处是什么?

            在网络层分片和组装的过程中,上层(网络层和应用层)是不知道的,它们只知道这是一个完整的报文,网络通信的时候丢包是有概率的,分片增加了丢包概率。

            上面的问题不是网络层说了算,要彻底解决问题,要在上层的传输层找答案。

             

            

            

            

             

             

            

             

            

             

  • 相关阅读:
    2023年NPDP报考指南,有你不知道的吗?
    【Qt】RK3399+Ubuntu18.04.6LTS命令安装Qt
    ⑧【MySQL】数据库查询:内连接、外连接、自连接、子查询、多表查询
    使用Cpolar和极简主义文件管理器构建个人云储存平台并进行公网访问
    React项目引入Antd后经过Webpack打包,没有任何报错,但是组件样式不生效。
    Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    阿里云 短信服务——发送短信验证码图文教程
    虚拟机的三种网络连接模式
    Elasticsearch 8.3中新增和改进的亮点!
    [python]如何操作Outlook实现邮件自动化
  • 原文地址:https://blog.csdn.net/weixin_49449676/article/details/130238692