《TCP/IP详解 卷一》第10章 UDP 和 IP 分片
目录
10.1 引言
10.2 UDP 头部
10.3 UDP校验和
10.4 例子
10.5 UDP 和 IPv6
10.6 UDP-Lite
10.7 IP分片
10.7.1 例子:IPV4 UDP分片
10.7.2 重组超时
10.8 采用UDP的路径MTU发现
10.9 IP分片和ARP/ND之间的交互
10.10 最大UDP数据报长度
10.11 UDP服务器的设计
10.11.1 IP地址和UDP端口号
10.11.2 限制本地IP地址
10.11.3 使用多地址
10.11.4 限制远端IP地址
10.11.5 每端口多服务器的使用
10.11.6 跨越地址族:IPv4和IPv6
10.11.7 流量和拥塞控制的缺失
10.12 UDP/IPV4和UDP/IPV6数据报的转换
10.13 互联网中的UDP
10.14 与UDP和IP分片相关的攻击
10.15 总结
10.1 引言
UDP(User Datagram Protocol):用户数据报协议。一种传输层协议。
IPv4中协议字段值:17。
特点:
有消息边界。
开销更小,因为没有TCP复杂机制。
当UDP应用程序每次调用send/write,就发出一个UDP数据报。
而TCP不一定,因为TCP可能分段,重组。
即TCP应用程序执行多次send/write调用会组合成一个数据包发送,或可能一个send/write调用被分成多个数据包发送。
10.2 UDP 头部
头部格式如下:

字段:
源端口
目的端口
长度:UDP报文总长度,包括头部和数据。
校验和:校验整个UDP报文。
每个socket在创建时必须指定协议类型(TCP或UDP),并绑定到特定端口。
因此,一个套接字不能同时监听TCP/UDP相同端口。
一个主机可以创建两个socket,分别监听TCP和UDP的相同端口号,表示两种不同服务。
10.3 UDP校验和
UDP校验和:校验范围覆盖UDP头部、UDP数据,伪头部。
伪头部(pseudo-header):
计算UDP校验和时,根据IP头信息生成的虚拟头部。
伪头部格式通常包括:
源IP、目标IP、协议类型(UDP),UDP数据报总长等。
作用:提供更多信息,确保校验更精确。
伪头部细节如下图:

NAT会改变报文IP和端口,所以经过NAT后需要重新校验和。
IPv4头中也有校验和,但只校验IPv4头内容,不包括IP载荷。
在每跳都要重新计算,因为TTL字段值减小。
小结:
IPv4头的校验和字段:只校验IPv4头内容。
传输层TCP/UDP头的校验和字段:校验范围不仅包含传输层头,还有载荷。
10.4 例子
10.5 UDP 和 IPv6
IPv6中TCP/UDP都需要伪头部来计算校验和。
Teredo隧道:
IPv6数据被封装成IPv4 UDP数据报后,发给Teredo中继,中继解封装后把IPv6报文转发给主机。
Teredo和GRE对比:
通用性:
GRE更通用,可封装任何类型数据包。
Teredo只用于IPv4 UDP封装IPv6数据。
实现方式:
GRE:不需要服务器或中继。
Teredo:需要服务器和中继。
10.6 UDP-Lite
UDP:校验是可选的,要么校验整个UDP报文,要么不校验。
UDP-Lite:对UDP数据一部分校验,而不是整个数据报校验。
所以未校验部分,容忍比特差错。
UDP-Lite:有单独的IPv4协议和IPv6协议号。算是一种新的传输层协议。
所以UDP- Lite有一个校验和覆盖范围字段,表示需要校验哪部分数据。
最小值为8,即只校验UDP-Lite头。
特殊值:0,表示校验整个负载。
socket简化程序举例,设置UDP-Lite校验和覆盖范围:
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE);
int send_cscov = 8; // 只校验UDP-Lite头。
setsockopt(sockfd, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, &send_cscov, sizeof(send_cscov)) ;
int recv_cscov = 0; // 校验整个负载
setsockopt(sockfd, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, &recv_cscov, sizeof(recv_cscov));
}
10.7 IP分片
IPv6只允许源主机分片,不允许中间转发设备分片,可减少中间设备负担。
IPv4既允许源主机分片,也允许中间路由器分片。
IP数据报大于MTU则分片。
被分片IP数据报,到了目的地才会重组,这样设计有两个原因:
1. 减轻中间路由器转发负担。
2. 同一数据报的不同分片可能经不同路径到达目的地,此时路径上路由器不能收到所有分片,搜到没有能力重组原始数据。
10.7.1 例子:IPV4 UDP分片

数据报分片后,每个分片IPv4头中的总长度字段被修改成该分片的总长度。
任一分片丢失,整个IP数据报无法完整接收。
当TCP报文的一个分片丢失了,TCP协议栈会重传整个TCP报文段,所以通常尽量避免TCP分片。
除最后一个分片外所有分片数据部分应是8字节倍数。
tcpdump为了能打印除了第一个分片外的其他分片的端口号,尝试重组其他分片的数据报,以恢复只出现在第一个分片的UDP头部中的端口号。
10.7.2 重组超时
当任一分片最先到达时,IP层就启动计时器。
若超时前未收到所有分片,无法重组源报文,会丢弃所有分片,防止缓存耗尽。
超时时间:一般30s,60s。
只有接收到了第一个分片并且分片重组失败时,才产生ICMP错误。
10.8 采用UDP的路径MTU发现
PMTU:路径MTU 。
PMTUD:路径MTU发现。
作用:发现路径中MTU的最小值。发送报文不超过MTU,防止分片。
UDP PMTUD原理:
源端发送一个较大UDP数据报,并设置 DF(Don't Fragment)标志,确保不被分片。
某个中间路由器发现数据报超过其出接口MTU,则丢弃该数据报并回复"Packet Too Big" 的ICMP 错误消息给源端。
源端收到ICMP错误消息后,得到其中指示的MTU。于是重新发送较小的UDP数据报。
重复该过程就获得一个可在所有路由器通过的MTU,即路径最小MTU,PMTU。
IP层会基于每个目的地址缓存一个PMTUD值,有到该目的地报文则更新,否则超时需要重新尝试PMTUD。
PPPoE MTU:1492
1500字节去除了6字节PPPoE头部,2字节PPP头部。
10.9 IP分片和ARP/ND之间的交互
10.10 最大UDP数据报长度
理论一个IPv4数据报的最大长度是65535字节。
但实际存在限制,如:
1. 系统,setsocketopt设置收发缓存大小。
2. 应用程序。read/write指定读写大小数目小于一个UDP数据报,大多数时候发生API截断数据报,丢弃数据报里超过接收应用程序指定字节数的数据。
MSG_TRUNC标志位:
当socket收到超过recv函数指定接收缓冲区大小时,如果设置该标志位,系统将丢弃缓冲区以外数据,并且不报告任何错误,而是正常返回已接收数据长度。
MSG_TRUNC使用方法:
len = recvfrom(sockfd, buf, BUF_SIZE, MSG_TRUNC, (struct sockaddr *)&client_addr, &client_len);
如何获取截断数据大小:
socklen_t optlen = sizeof(recv_len);
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &recv_len, &optlen);
而TCP是连续的字节流,没有消息边界,不会被截断。
10.11 UDP服务器的设计
10.11.1 IP地址和UDP端口号
SO_REUSEADDR:
一个socket选项,当一个socket被关闭后,它的端口号会继续一段时间的被占用。
在这个时间内,其他程序无法绑定相同端口号,出现"Address already in use"错误。
设置SO_REUSEADDR选项后,当socket关闭后,立即可以被其他程序绑定,无需等待一段时间。
如何设置SO_REUSEADDR属性:
int reuse = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
10.11.2 限制本地IP地址
两种策略:
1. 只有报文目的IP地址是该接收接口的IP时,才接收数据。
2. 任何本地接口均可接收到目的IP是某本地接口之一的数据。
10.11.3 使用多地址
一台主机上,可以开启多个服务器进程,都使用同一个端口号,但每个服务器进程使用不同本机IP地址。
通过ip addr add给本机设备配置多个IP地址。
此时需要用SO_REUSEADDR选项告诉系统允许重用相同的端口。
10.11.4 限制远端IP地址
可设置是否只接收来自指定源IPv4地址和端口号的UDP数据报。
10.11.5 每端口多服务器的使用
10.11.6 跨越地址族:IPv4和IPv6
10.11.7 流量和拥塞控制的缺失
UDP没有流量和拥塞控制机制。
10.12 UDP/IPV4和UDP/IPV6数据报的转换
10.13 互联网中的UDP
UDP占据了的互联网流量的10% ~ 40%,随着P2P应用增加,UDP流量也在上升。
互联网总体流量只有极少是分片的(大约分组数的0.3%,字节数的0.8%),而其中分片流量的68.3%是UDP。
常见分片流量如:
多媒体视频流量(应用层大包)
VPN隧道中封装/隧道流量(多层封装)
10.14 与UDP和IP分片相关的攻击
常见UDP DoS攻击:
1. 短时间大流量。UDP没有流控。
2. 放大攻击。伪造IP源成受害者地址,并设置目的地址为广播。于是广播目的地都回复报文给该受害者。
3. 泪滴攻击。构造一个重叠偏移分片,可覆盖前一分片部分数据。
4. 发送不带任何数据的分片,攻击IPv4重组程序。
10.15 总结
UDP是简单协议。
需要组播广播时使用UDP,可避免连接开销。
UDP使用场景:多媒体,P2P。
相关文章:
《TCP/IP详解 卷一》第10章 UDP 和 IP 分片
目录 10.1 引言 10.2 UDP 头部 10.3 UDP校验和 10.4 例子 10.5 UDP 和 IPv6 10.6 UDP-Lite 10.7 IP分片 10.7.1 例子:IPV4 UDP分片 10.7.2 重组超时 10.8 采用UDP的路径MTU发现 10.9 IP分片和ARP/ND之间的交互 10.10 最大UDP数据报长度 10.11 UDP服务器…...
MyBatisPlus(SpringBoot版)的分页插件
目录 一、前置工作: 1.整体项目目录结构 2.创建普通javamaven项目。 3.导入依赖,改造成springboot项目 4.配置启动类 5.创建service接口及其实现类 6.创建接口Mapper 7.配置数据源 8.创建数据库表 二、使用MP(mybatisplus)的分页插件 二、使…...
【小沐学QT】QT学习之信号槽使用
文章目录 1、简介2、代码实现2.1 界面菜单“转到槽”方法2.2 界面信号槽编辑器方法2.3 QT4.0的绑定方法2.4 QT5.0之后的绑定方法2.5 C11的方法2.6 lamda表达式方法2.7 QSignalMapper方法 结语 1、简介 在GUI编程中,当我们更改一个小部件时,我们通常希望…...
SpringMVC总结
SpringMVC SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装。 对于SpringMVC我们主要学习如下内容: SpringMVC简介 请求与响应 REST风格 SSM整合(注解版) 拦截器 SpringMVC是处理Web层/表现层的框架ÿ…...
JS一些重要函数
防抖函数 避免短时间内的函数多次调用影响性能 function debounce(func , wait){let timer;return (...args) > {clearTimeout(timer);timer setTimeout(() > {return func(args)} , wait)} } 函数柯里化 将多参函数以单参的形式传递 function curry(fn){return func…...
基于视觉识别的自动采摘机器人设计与实现
一、前言 1.1 项目介绍 【1】项目功能介绍 随着科技的进步和农业现代化的发展,农业生产效率与质量的提升成为重要的研究对象。其中,果蔬采摘环节在很大程度上影响着整个产业链的效益。传统的手工采摘方式不仅劳动强度大、效率低下,而且在劳…...
算法D32 | 贪心算法2 | 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II
122.买卖股票的最佳时机II 本题解法很巧妙,大家可以看题思考一下,在看题解。 代码随想录P 只收集每天的正利润,利润可以每天分解。 Python: class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices)<2: retur…...
【iOS ARKit】协作 Session 实例
协作 Session 使用注意事项 协作 Session 是在 ARWorldMap 基础上发展起来的技术,ARWorldMap 包含了一系列的地标、ARAnchor 及在观察这些地标和 ARAnchor 时摄像机的视场(View)。如果用户在某一个位置新创建了一个 ARAnchor,这时…...
云原生精品资料合集(附下载)
云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声,以应用价值为中心的云原生时代已经到,所以IT人员学习云原生正当时!最近跟各位大神征集了云原生的教程,行业报告和最佳实践,总有一款适…...
JVM 第一部分 JVM两种解释器 类加载过程和类加载器
JVM是跨平台跨语言的虚拟机,不直接接触硬件,位于操作系统的上一层 跟字节码文件直接关联,和语言没有关系 一次编译成字节码文件,多次执行 虚拟机可以分成三部分:类加载器,运行时数据区,执行引…...
用Java语言创建的Spring Boot项目中,如何传递数组呢??
问题: 用Java语言创建的Spring Boot项目中,如何传递数组呢?? 在这个思路中,其实,Java作为一个后端开发的语言,没必要着重于如何传入,我们主要做的便是对传入的数组数据进行处理即可…...
[笔记] 使用 Java Swing 实现一个简单的窗口
Java Swing 是一个用于构建图形用户界面(GUI)的Java库,它提供了丰富的组件和工具,用于创建交互式的桌面应用程序。Swing 是 Java Foundation Classes(JFC)的一部分,它是 Java 平台的一种标准用户…...
2024.03.03蓝桥云课笔记——排序
sort简介 #include<algorithm> 使用的是快速排序 时间复杂度为O(nlogn) sort使用(默认是从小到大) 1.sort(起始地址,结束地址的下一位,*比较函数); #include<iostream> #include<algorithm> using namesp…...
Vue3和ElementPlus封装table组件
最近学习vue3.2并自己在写一个项目,然后发现好几个页面都是列表页,重复写table和column也是觉得累,学习的项目列表页不算多,要是公司项目就不一样了,所以就想着自己封装一个table组件,免去大量重复工作和co…...
第一篇:参考资料地址
javaGuide JavaGuide(Java学习&面试指南) | JavaGuide 清华学生总结的 小林coding labuladong labuladong 的算法笔记 | labuladong 的算法笔记 【华仔说技术】kafka的系列文章 https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg3MTcxMDgxNA…...
wordpress 开源主题
海外就医wordpress主题 出国看病、海外就医是越来越多中产家庭的选择,此wordpress主题适合做相关业务的公司官网。 https://www.jianzhanpress.com/?p5220 防护wordpress外贸主题 个人防护器具wordpress外贸主题,适合做劳动保护的外贸公司使用。 ht…...
【Linux网络命令系列】ping curl telnet三剑客
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
于月仙主动与赵本山握手表示欢迎,赵:怎么着要跟我第二次牵手啊?
于月仙主动与赵本山握手表示欢迎,赵:怎么着要跟我第二次牵手啊? --小品《乡村爱情》(中1)的台词 表演者:赵本山 于月仙 王小利 唐鉴军等 (接上) 咱们呢就给新人揭盖头 好 好长贵…...
Unity UGUI之Slider基本了解
在Unity中,Slider(滑动条)是一种常用的用户界面控件之一,允许用户通过拖动滑块来选择一个数值。常常应用于调节数值(如调节音量、亮度、游戏难度等)、设置选项等。 以下是Slider的基本信息和用法: 1、创建…...
【Linux】进程间通信之共享内存
文章目录 引入共享内存的原理共享内存的相关接口shmget()shmat()shmdt()shmctl() 共享内存的简单使用共享内存的特点 引入 进程间通信,顾名思义就是一个进程和另一个进程之间进行对话,以此完成数据传输、资源共享、通知事件或进程控制等。 众所周知&am…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
