数据链路层(Mac帧,报头字段,局域网通信原理),MTU,MSS,ip报文的分包与组装(ip报头字段介绍,组装过程,判断是否被分片/收到全部分片)

本文主要是介绍数据链路层(Mac帧,报头字段,局域网通信原理),MTU,MSS,ip报文的分包与组装(ip报头字段介绍,组装过程,判断是否被分片/收到全部分片),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

数据链路层

介绍

MTU

介绍

在哪一层分片

IP报文的分包与组装

16位标识

3位标志

13位片偏移

示例

组装过程

确定是否被分片

确定是否收到全部分片

 注意点

数据链路层与网络层的关系

Mac帧

Mac地址

报头格式

目的/源地址

类型

局域网通信原理

图解

碰撞问题 

MSS

引入

介绍


数据链路层

介绍

也属于网卡驱动层

  • 负责与实际硬件(网卡)通信,执行数据的发送和接收操作
  • 两者并不相同,网卡驱动层属于计算机操作系统的一部分,不在OSI模型中

因为网卡不支持一次接收过大的数据

  • 所以它倒逼上层一次不能交付过大的报文

所以上层在通信时,如果收到了大数据,需要将大数据分割成小的报文

  • eg:tcp层的滑动窗口需要分段,而不是把整个窗口的数据发送过去

MTU

介绍

MTU(Maximum Transmission Unit,最大传输单元) ,是指网络接口一次可以传输的最大字节数

  • 网络接口 -- 指计算机或网络设备与网络进行通信的硬件或软件接口
  • 最常见的物理网络接口就是网卡

不同的数据链路协议(如以太网、Wi-Fi、PPP)可能具有不同的 MTU 值

  • 对于以太网,通常的 MTU 是1500字节

如果上层协议生成的报文(如 TCP 报文)比 MTU 大,则需要将其分片以适应网络接口的 MTU 限制

  • 因为链路层一旦交付给下层,网卡就会直接发送数据了,所以相当于在链路层就要有MTU规定,同样它也会影响上层
  • 注意,这里说的"上层协议生成的报文"也就是Mac帧里的有效载荷部分,所以实际上MTU规定的是Mac帧里的有效载荷的大小(网络层交付的报文大小)
  • (这些都会在下面详细介绍)

在哪一层分片

虽然下层这么规定了,但是传输层(也就是tcp层)发送的数据就是特别大怎么办?

  • 所以,ip层(网络层)需要对报文分片

为什么不是在数据链路层呢?

  • 还记得吗,网络数据都是广播发送的,传到链路层后判断是否是发给自己的,不是就丢弃
  • 报文一路上都要经过多个设备,如果每经过一个设备就要进行组装和分片(要保证数据的完整性),太麻烦了
  • 所以放在ip层,等数据包收全后再进行组装,然后交付给上层最好

本身分片就需要针对不同网络的MTU进行

  • 网络层可以根据网络的需求对数据包进行分片
  • 但链路层只处理直接相连的网络节点之间传输数据帧,不会涉及MTU的变化
  • 所以放在网络层分片最合理

IP报文的分包与组装

也就是报头的第二行,是有关分片和组装的字段

报头中其他字段的介绍 -- 传输层和网络层的关系,ip协议+ip地址+ip报头字段介绍(4位TOP字段,8位生存时间(ttl)),ip地址和端口号的作用-CSDN博客

16位标识

每个ip报文的标识不同,但[同一个报文分片后的部分]的标识相同

3位标志

第一位 -- 保留位,默认为0

第二位 -- 是否允许分片(0表示允许)

第三位 -- 结束标记(0表示是最后一个分片),也叫做更多分片(如果是1,就代表还有其他分片)

13位片偏移

记录的是该分片在原始报文中的偏移量

示例

假设有一个3000字节的报文(包含报头),按照1500字节来分片

那么,我们将会得到三个分片:

  • 注意,每个分片都要有ip报头

组装过程

  • 所有分片聚集在一起(根据相同的标识)
  • 按照片偏移排序
  • 去掉除第一个外报文的报头,将各部分拼接在一起

确定是否被分片

但是,如何知道该报文是被分片的?

如果报文的3位标识中:

  • 更多分片位=0,片偏移=0,说明该报文不是分片,它是一个完整的报文
  • 那么根据逆反条件,更多分片位=1 || 片偏移不为0,则说明它是分片

如果细分一下:

  • 更多分片位=0,片偏移不为0,该报文是最后一个分片
  • 更多分片位=1,片偏移=0,该报文是第一个分片
  • 更多分片位=1,片偏移不为0,该报文是中间的分片

确定是否收到全部分片

那么又如何知道已经收到了所有的报文?

  • 只要判断是否有丢失的分片即可

分片有没有丢失,丢失了哪一段我们是可以知道的

  • 丢第一个 -- 没有片偏移为0的报文
  • 丢中间 -- 后一个片偏移和前面的总长度对不上
  • 丢最后一个 -- 没有"更多分片"位=0的报文

 注意点

虽然特殊情况都是可以判断出来的,但并不建议分片

  • 因为一旦分片丢失,原始报文是需要全部重发
  • 相当于增加了报文丢失的概率

但是,强行不分片也不行,因为网卡的上限是客观存在的 ; 又因为[数据的一次发送量]网络层说了不算,它只是个跑腿的

  • 所以,只能倒逼传输层一次不能发送过大报文
  • 那这个过大究竟是多大呢 -- MSS(下面会介绍到)

重新说回我们的数据链路层

数据链路层与网络层的关系

解决的是两台直接相连的设备之间进行数据交付的问题,而网络层是解决跨网络传输

  • 也就是网络层进行路径抉择,链路层进行点对点传输

 

Mac帧

Mac地址

使用ifconfig命令查询出来的ether,就是该设备中网卡的mac地址

  • 用于在同一个局域网中,区分不同的设备

报头格式

  • 因为是定长报头,所以可以解包
目的/源地址

都是Mac地址

  • 目的地址是当前的下一跳设备
  • 源地址是当前设备
类型

用于区分有效载荷

  • 可以实现分用,不同的数据类型要交给不同的上层协议

局域网通信原理

在之前我们已经简单介绍过局域网内的通信过程 -- 局域网(介绍+如何共享资源),以太网+令牌环网络,以太网内部通信过程(mac地址,数据暴露问题,碰撞问题),换角度看待通信过程 -- 临界资源_以太网的通信交互通信过程-CSDN博客

图解

这里我们将Mac帧代入再来看局域网:

  • 会发现每经过一个设备,Mac帧都是经过重新封装,而只有相邻的设备在同一个局域网中,所以我们可以得出一个结论 -- Mac帧只在局域网中有效

碰撞问题 

因为碰撞问题,需要保证同一时刻只有一台主机在网络中传输

  • 所以,在局域网通信时,发送短的数据帧更好

短的数据帧有以下好处:

  • 在时间维度上让更多的数据在局域网中岔开发送(更快的发送过程和传输过程)
  • 详细来说就是 -- 允许网络在单位时间内处理更多的帧,减少了碰撞检测的窗口时间,从而减少了重传的机会,优化了整体传输速度

这也就是为什么网卡规定不能一次传输过大的数据

  • 这是基于局域网通信原理来的,都是为了最大化网络的吞吐量和可靠性

 

MSS

引入

因为有这个硬性规定,所以倒逼网络层一次不能发送超过1500字节的数据(以以太网为例),这里有两种做法:

网络层进行分片 -- 不建议,会增加丢包概率

让传输层一次不能发送过大数据 -- 本身传输层就是负责决定数据发送的,所以直接从它解决问题

  • 数据量=1500字节-20字节(ip报头)=1480字节

而传输层的数据都是从它的发送缓冲区里拿取的

  • 数据量=1480字节-20字节(tcp报头)

这里的1460就是前面提到的MSS,是传输层的最大发送量

  • 正因为这个规定,所以传输层不能将滑动窗口内的所有数据发送出去,而是要分段发送

介绍

在TCP连接中,每个TCP段中可以承载的最大有效负载的字节数

  • MSS = 最大传输单元 (MTU) - TCP头部大小 - IP头部大小

双方要协商好MSS的值,因为不同设备MTU不同,可能MSS也不同

  • 以双方中MSS的最小值作为通信中使用的MSS,从而确保数据不会因网络路径上最小的MTU而被分片,可以保证尽量少的分片
  • 而这个协商就发生在tcp三次握手

这篇关于数据链路层(Mac帧,报头字段,局域网通信原理),MTU,MSS,ip报文的分包与组装(ip报头字段介绍,组装过程,判断是否被分片/收到全部分片)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1116290

相关文章

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap