计算机网络那些事之 MTU 篇 pt.2

哈喽大家好,我是咸鱼

在《计算机网络那些事之 MTU 篇 》中,咸鱼跟大家介绍了 MTU 是指数据链路层能够传输的最大数据帧的大小

如果发送的数据大于 MTU,则就会进行分片操作(Fragment);如果小于 MTU,就会在实际数据内容后面添加填充数据(Padding),使得数据包总长度达到最小长度要求

TCP 因为是有连接的协议,连接在建立的时候就有 MSS(TCP 报文段中数据部分的最大长度) 的协商,以便在传输过程中进行分片

在网络传输的过程中,如果中间设备(例如路由器)的 MTU 比较小,就会 MSS clamping

MSS clamping 是一种 TCP 优化技术,用于解决 TCP 数据包在传输过程中可能发生的分片问题

它会检查 TCP SYN 包中的 MSS 选项,并将其值与网络链路的 MTU 进行比较

如果 MSS 值大于 MTU,就将 MSS 值设置为 MTU 减去 IP 头部和 TCP 头部的长度,从而保证 TCP 数据包的大小不会超过网络链路的 MTU,避免发生 IP 分片

在 TCP 连接建立后,双方会根据 MSS 值来控制每个 TCP 数据包的大小,从而保证 TCP 数据包不会超过网络链路的 MTU,提高网络传输的效率

但是对于面向无连接的协议(例如 UDP ),这时候该怎么办呢?

我们知道以太网规定 MTU 范围上限为 1500 字节,那么理论上 UDP 能传输的数据包大小上限为:

MTU(1500) - IP Header(20) - UDP Header(8) = 1472 字节

  • 如果 UDP 数据包小于等于1472 个字节,那么正常发送不用分片
  • 如果 UDP 数据包超过 1472 个字节,那么移交网络层进行分片并在接收方进行重组

但我们需要知道的是,UDP 包进行分片的时候不像 TCP 那样每个分片里面都复制一个 Header

而是第一个分片有 UDP Header,其余的都没有

所以接收方拿到 UDP 分片包之后在传输层就得先进行重组成一个完整的 UDP 包然后才能交给上一层

这样就会导致一个问题:如果在传输过程中其中一个 UDP 分片包丢了,造成 UDP 包重组失败,接收方会把整个包给丢掉

但是又因为 UDP 没有重传机制,就会导致 UDP 发送方不知道接收方丢了这个包

然后发送方就会一直发包,接收方一直丢包

所以说最好不要发超过接收方 MTU 大小的 UDP 数据包

但面向无连接的 UDP 是怎么知道对方 MTU 的呢?(TCP 有 MSS 协商)

为此我在虚拟机上简单做了一个实验

  • 环境
    • CentOS 7
  • 服务器 A
    • IP:192.168.149.130
    • MTU:800
  • 服务器 B
    • IP:192.168.149.131
    • MTU:1500

然后用 B 服务器去 ping 服务器 A,发送一个大小为 1500 bytes 的数据

# -M do 表示不分片
# -p 选项用于指定数据包的内容
# -c 2 指定发送数据包的数量为2
# -s 指定数据包的大小
ping -c 2 -s 1000 -M do -p $(echo -n abcdefghijklmnopqrstuvwxyz | xxd -p)   192.168.149.130

在这里插入图片描述

结果发现服务器 A 全部接受了,按理说 A 的 MTU 是 800,又因为设置了不分片,应该丢弃这个包才对

然后我们用 B 服务器去 ping 服务器 A,发送一个大小为 1600 bytes 的数据

发现超出服务器 B 的 MTU (1500)了,又因为不允许分片,导致包不能发出

ping -c 2 -s 1600 -M do -p $(echo -n abcdefghijklmnopqrstuvwxyz | xxd -p)   192.168.149.130

在这里插入图片描述

跟我想象的不太一样,服务器 A 收到服务器 B 发送的超过自身 MTU 大小的包应该是丢弃,然后回复一个:

Type=3 (Destination Unreachable) and code=4, packet too big and DF is set

表示发送方数据包无法到达目的地且无法分片

后面我查了一下,应该是本地环境即两个虚拟机之间的网络比较简单,导致网卡能接受这种不合理的包,如果有懂的小伙伴可以私信我

但是这个实验至少证明了一点:即服务器不会去关心对方的 MTU,只会根据自己的 MTU 去进行分片

然后我又查阅了大量的资料,我看到一个比较贴切的答案就是:
在这里插入图片描述
我们来看下上面这段内容,可以得出

在 RFC 中,Internet (IPv4) 标准规定 MTU 最小是 576 bytes

所以对于 UDP 来讲,能发的有效数据(Payload)只要不超过 508 bytes

576 bytes (MTU) - 60 bytes (IP header 20 bytes + IP option 0-40 bytes) - 8 bytes (UDP Header)= 508 bytes

在这里插入图片描述
我管你服务器的 MTU 是多少,我只发送全世界最小的二层包,总没问题了吧?

很多情况下 IP header 是达不到 60 bytes的,所以一般 UDP 的 Payload 也会是是 512 bytes

总结一下:

  • 不同于 TCP ,UDP 这个简单的协议并不关心对方的 MTU 这些问题;如果你要基于 UDP 实现一个协议,就要自己处理超过 MTU 的问题
  • 为了避免分片问题,UDP 只发不超过 IPV4 MTU 范围下限(576 bytes)的包(即UDP 数据包的最大 Payload 是 512 字节
  • 上述讨论针对的是 IPV4,而非 IPV6

Beej’s Guide to Network Concepts

domain name system - Why DNS through UDP has a 512 bytes limit? - Server Fault

MTU 和 UDP (以及基于 UDP 的协议) | 卡瓦邦噶! (kawabangga.com)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot整合Redis缓存管理

1. 添加 Spring Data Redis 依赖启动器。在 chapter06 项目的 pom.xml 文件中添加 Spring Data Redis 依赖 启动器。 <!-- 引入整合 Redis 缓存的依赖启动器 --> <dependency> <groupId> org.springframework.boot </groupId> <artifactId>…

Java安全——应用安全

Java安全 Java 应用安全 JCE&#xff08;Java Cryptography Extension&#xff09;java加密扩展包 Java Cryptography Extension&#xff08;JCE&#xff09;是一个可选的Java标准扩展&#xff0c;提供了一组用于加密、密钥生成和密钥协商等功能的类和接口。JCE包含了导入、生…

android checkBox的使用

一、前言&#xff1a;之前工作中遇到的checkbox的使用是左边一个复选框&#xff0c;右边一个text。系统学完之后发现那样做的话有点别扭&#xff0c;还是中规中矩的舒坦。记录一下学习经过。 二、代码展示&#xff1a; 1.使用系统自带的checkbox插件。 创建一个CheckBoxActiv…

Solr框架 01 Solr框架简介,安装,配置(Analysis,Dataimport)

Solr简介&#xff1a; Solr是一个高性能&#xff0c;基于Lucene的全文搜索服务器。同时对其进行了扩展&#xff0c;提供了比Lucene更为丰富的查询语言&#xff0c;同时实现了可配置、可扩展&#xff0c;并对查询性能进行了优化&#xff0c;并且提供了一个完善的功能管理界面&am…

CentOs中文件权限命令

文件权限&#xff1a; ls -l命令查看文件详情&#xff0c;前十位就是文件的类型和权限 第一位&#xff1a;类型&#xff1a; - 普通文件 d 目录 l 链接文件&#xff08;快捷方式&#xff09;link 2~4位&#xff1a;所有者的权限 5~7位&#xff1a;所有者所在组其它用户的权限 …

2021 年高教社杯全国大学生数学建模竞赛 E 题 中药材的鉴别 第一题

目录 1.数据预处理 1.1 数据基本信息探索 1.2 数据可视化 1.3 异常值处理 2. 数据特征值提取 2.1 数据标准化 2.2 PCA提取特征值 3. 数据聚类鉴别药材种类 3.1 肘部图确定K值 3.2 轮廓系数图确定K值 3.3 数据聚类 3.4 聚类结果可视化 4. 研究不同种类药材…

【案例实战】SpringBoot整合Redis实现缓存分页数据查询

正式观看本文之前&#xff0c;设想一个问题&#xff0c;高并发情况下&#xff0c;首页列表数据怎么做&#xff1f; 类似淘宝首页&#xff0c;这些商品是从数据库中查出来的吗&#xff1f;答案肯定不是&#xff0c;在高并发的情况下&#xff0c;数据库是扛不住的&#xff0c;那么…

Redis分布式问题

Redis实现分布式锁 Redis为单进程单线程模式&#xff0c;采用队列模式将并发访问变成串行访问&#xff0c;且多客户端对Redis的连接并不存在竞争关系Redis中可以使用SETNX命令实现分布式锁。当且仅当 key 不存在&#xff0c;将 key 的值设为 value。 若给定的 key 已经存在&…

『赠书活动 | 第十三期』《算力经济:从超级计算到云计算》

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 『赠书活动 &#xff5c; 第十三期』 本期书籍&#xff1a;《算力经济&#xff1a;从超级计算到云计算》 赠书规则&#xff1a;评论区&#xff1a;点赞&#xff5c;收…

全志V3S嵌入式驱动开发(开发环境再升级)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们陆陆续续开发了差不多有10个驱动&#xff0c;涉及到网口、串口、音频和视频等几个方面。但是整个开发的效率还是比较低的。每次开发调试的…

Matlab论文插图绘制模板第105期—带缺口的分组填充箱线图

在之前的文章中&#xff0c;分享了Matlab带缺口的分组箱线图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下带缺口的分组填充箱线图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自…

筹码分布图高级用法——历史换手衰减系数自动计算公式

在使用筹码分布图时&#xff0c;很多人习惯于采用软件的默认设置&#xff0c;然而默认设置不一定能满足我们的要求。今天将向大家介绍筹码分布图的高级用法——历史换手衰减系数&#xff0c;并编写历史换手衰减系数自动计算公式。有些网友认为通过修改衰减系数&#xff0c;可以…