Linux——UDP/TCP协议理论
1. UDP协议
1.1 UDP协议格式
系统内的UDP协议结构体:
注1:UDP协议的报头大小是确定的,为8字节
注2:可以通过报头中,UDP长度将UDP协议的报头和有效载荷分离,有效载荷将存储到接收缓冲区中等待上层解析。
注3:UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议后进行后续传输动作
注4:UDP具有接收缓冲区,该缓冲区不能保证收到UDP报文的顺序和发送UDP报文的顺序一致,如果缓冲区满了,再到达的UDP数据会被丢弃。
认知:操作系统会接收各种协议的大量的报文,因此os需要对报文做管理,而每个报文都是一个结构体(类),该类保存了报头和有效载荷等其他相关属性信息,该结构体可以通过某些数据结构统一管理起来。
注1:一个struct sk_buff对应一块内存空间记录报文数据,这和先前学习 struct file_struct 也会指向对应file是类似的
注2:网络通信,每一层都是报头+有效载荷的结构。
head和end标志整个缓冲区的开始和结束,假设数据从应用层一直递交到网络层,开始时data指向应用层数据开始地址处,tail指向尾部,每一层加入新的报头时,data往上添加
2. TCP协议
2.1 TCP协议格式
2.2 序号和确认序号
认知:TCP协议是面向字节流的协议,序号和确认序号是报文中有效载荷在整个数据流中的编号,如果将字节流抽象成一个一维数组,那么编号就是数组下标,即序号确定了报文有效载荷的开始与结束
注:SYN和FIN标志位会占用序号,其他标志位不会占用序号
2.3 四位首部长度
认知:用于记录TCP报头长度,基本单位是4字节,TCP协议规定了报头的长度范围为20~60字节,因此四位报头长度的数值应为[5,15]。
2.4 窗口大小
现象:TCP协议,通信的双方存在各自的接收缓冲区,实际通信过程中,如果多个客户端向服务端发起通信请求,那么可能会导致服务端的接收缓冲区占满。占满之后,多余的客户端请求会被丢弃,导致资源浪费和低效。
认知:为了解决上述问题,窗口大小的目的是为了流量控制,是为了告诉对方,我的接收缓冲区剩余空间大小,避免资源浪费和低效。当客户端知道了服务端的窗口大小,会控制自己的发送速度。
2.5 6/8位标志位
问:为什么TCP报头中要有标志位?
答:接收方会收到不同类型的TCP报文,针对不同的报文类型,接收方要有不同的做法,因此需要有标志报文不同类型的字段,所以就需要这个标志位。
注:实际是位段,属于哪个类型就哪个位置一,否则置零
2.5.1 SYN标志位
作用:同步、建立连接,在握手过程中使用的标志位
2.5.2 ACK标志位
作用:表明是一个应答报文
注:大多数情况下,ACK标志位常置为1,只有第一次握手时为0,后续讨论。
2.5.3 FIN标志位
作用:表明是一个关闭连接的报文
2.5.4 PSH标志位
作用:催促接收方尽快将接收缓冲区内的数据交给上层
2.5.5 RST标志位
作用:连接重置报文,双方连接出现任何问题时,都可以进行重置
3. TCP协议中的三次握手☆☆☆
3.1 第一次握手
解释:
• SYN = 1:
SYS标志位置1,SYN标志位是用来建立连接的,因此,当客户端第一次向服务端发起握手请求时,报文中的SYN标志位会被置1
• Seq:
是客户端OS随机生成的一个序列号,用于建立连接
• ACK = 0:
第一次发送请求时,不会包含应答,所以ACK置0
细节1:双方在握手过程中,实际发送的是报文!
细节2:第一次握手时,报文中只包含报头数据,不包含有效载荷
3.2 第二次握手
服务端在接收到客户端发来的报文时,服务端也会将SYN置1,同时发送一个随机序号y,同时将确认序号置为:Ack = x + 1,告知客户端,下一次从x + 1序号位置发送数据。
细节:第二次握手时,报文中依然只有报头,没有有效载荷
3.3 第三次握手
客户端接收到服务端发送来的应答,表明x+1之前的序号已经连接成功,第一次握手成功,此时客户端向服务端发送应答 Ack = y + 1,告知服务端,下次从y+1开始的序号发送数据。
当服务端再次收到客户端的应答时,双方都建立了可靠的通信。
☆☆☆细节:ACK不占用序号,所以在双方三次握手完毕,建立起连接后,客户端的确认需要就为seq = x + 1;客户端在后续发送带有有效载荷的数据时,就从该序号开始,这样双方在第一次通信时,就能够保证发送方的起始序号和接收方的确认序号能够一致
3.4 细节问题
问:前面我们说了,序号是用来形容有效载荷的,而且第一次握手和第二次握手中,不包含有效载荷,那么第一次握手和第二次握手中的序号Seq是什么?
答:SYN和FIN标志位会被计入到序号中,只占1位
问:序号和确认序号究竟是什么?有什么作用?
答:
• 序号:每个字节在数据流中的开始位置,告知对方这次发送的数据是从该序号开始的,每个字节都有唯一序号,在数据发送过程中不断递增。
• 确认序号:告诉接收方期望收到的下一个字节的序号,并告知对方我已经成功收到了你从开始序号到该序号为止的数据
举两个例子:
1.三次握手(假设握手成功):
• 客户端向服务端发送序号Seq = 100,有效载荷的大小和SYN标志位决定了序号的范围,即1
• 服务端接收客户端发来的序号 Seq = 100,服务端OS解析TCP报文长度,得知序号范围为100~101,所以Ack = Seq + 1 = 101,同时随机设置一个序号Seq = 200,发送给客户端。
• 客户端接收到服务端的应答,表明从100~101的序号服务端已经全部接收完毕,客户端OS会解析服务端发送来的报文,得知序号范围为200~201,所以应答 Ack = Seq + 1 = 201,发送给服务端。
2.握手成功后正常通信(假设标志位全为0,双方有效载荷的大小为50字节):
• 客户端向服务端发送序号Seq = 100
• 服务端接收客户端发来的报文,告知客户端下次从150序号开始发送数据,同时回复Ack = 150,并随机发送自己的序列号 1000
• 客户端接收服务端的应答,客户端的数据从150序号开始发送,同时告知服务端下次数据从1050序号开始发送。
问:为什么三次握手前两次需要有SYN标志位?
答:SYN是用于建立连接的标志位,TCP通信是全双工通信,需要确认双方可以互通
问:为什么要三次握手?
答:1.验证服务端和客户端能进行全双工通信的最短的方式,本质是验证网络畅通;2.以最小成本100%确认双方通信意愿
问:假设第三次握手时,服务端没有收到来自客户端的回应?
答:那么握手就失败了,客户端觉得,只要把ACK发出,他就认为三次握手完成,但实际情况是:服务端没有接收到客户端的回应,就会导致出现一个建立是否成功认知不一致的问题,即客户端认为连接建立成功,而服务器认为连接建立失败。
此时若客户端向服务端发送报文时,服务器就会识别到当前没有成功建立连接,就会向客户端发送一个带RST标志位的报文,要求重新建立连接。
细节1:connect发起握手请求,三次握手的过程由 client OS 和 client OS 完成,accpet不参与三次握手的过程
细节2:丢包问题,当发送方收不到应答 && 接收Ack超时时
问:这个时间有多长?
答:根据网络情况定长短,以500ms为基准,第二次传以500*2为基准 ,第三次传以500*4为基准,如果500*4成功了,下次就以500*4为基准
细节3:TCP在握手时,向对方传递的不仅仅是SYN、ACK标志位,而是一整个报文,保温内部有对方的窗口大小信息,因此在握手过程中,双方就确认了对方的窗口大小信息,以便控制自己滑动窗口的大小进行流量控制
4. TCP协议中的四次挥手☆☆☆
4.1 四次挥手的过程(假设客户端主动断开连接)
第一次挥手:
客户端调用close(fd); 关闭套接字,发送带有FIN标志位的报文,表示要关闭客户端,客户端进入FIN_WAIT_1状态;
第二次挥手:
服务端接收客户端发来的FIN报文,返回带有ACK的报文,表示服务端知道客户端要关闭了,此时服务端进入CLOSED_WAIT状态
第三次挥手:
服务器处理完剩余数据后,主动发送带有FIN标志位的报文,表示要关闭服务端,服务端进入LAST_ACK状态
第四次挥手:
客户端收到服务端的FIN后,发送ACK表示客户端知道服务端关闭了,此时客户端进入TIME_WAIT状态,大约两个MSL时间后,客户端完全关闭进入CLOSED状态
细节:上述是客户端主动断开连接的情况,如果是服务端主动断开连接,对应状态变化只需要互换即可。
4.2 细节问题
问:如果客户端关闭/退出,服务端不关会出现什么情况?
答:服务端会一直处于close_wait状态,依旧占用fd,连接没有释放 → 服务端文件描述符泄漏问题
注:客户端关闭时,服务端也需要调用close(),关闭对应套接字,即发起第三次挥手过程。
问:MSL是什么?
答:MSL:TCP协议通信双方互发的历史报文中,存活时间最大的报文。
问:为什么要等待两倍的MSL?在回答这个问题之前,需要对另一个现象做一下描述。
现象:当发送方发送一个数据时,发送方判断超时,认为该数据已经丢失,但实际情况可能是该数据还在路由器的等待队列当中,即还存在于网络当中。此时如果断开的服务器立马重启,那么在建立连接的过程中,网络中的数据可能会被重新接收,从而影响建立连接的过程
答:为此发起断开的那一方在最后一次发送ACK时,需要处于TIME_WAIT状态同时等待两倍的MSL时间,为的就是网络中两个方向上残存的报文消散,避免引起下一次建立通信连接时出错。
注1:这也就是为什么主动断开的那一方为什么无法立刻重启服务器,因为他处于TIME_WAIT的状态,对应的端口号无法被使用,得换一个端口号才能重启。历史上被丢弃的报文就不会和新的连接配得上(源ip port 目的 ip port),双方os就能够甄别出来这是陈旧报文
注2:如果需要让服务端又要处于TIME_WAIT状态,又要立即重启,需要重新设置套接字:
5. 滑动窗口
滑动窗口的作用:用于流量控制,是流量控制的具体实现方案
滑动窗口的大小:无需等待确认应答而可以继续发送数据的最大值
滑动窗口是发送缓冲区的一部分:窗口左边是已经发送完毕的数据,会被清空;窗口内部是待发送的数据;窗口右边是尚未发送的数据。
问:滑动窗口的大小有谁决定?
答:滑动窗口的大小由对方接收能力决定,简单点的话,滑动窗口的start = 报文确认序号
问:滑动窗口可以向左滑动吗?
答:不可以
问:滑动窗口可以变小、变大、不变以及为零吗?
答:可以
问:如果对端的窗口大小满了呢?
答:滑动窗口的大小设置为0,
1. 发送端周期性的进行窗口探测(发送只带报头的报文)来获取对端窗口大小属性。
2. 对端窗口更新时也会向发送端发送窗口更新的报文(报头)
问:如果滑动窗口内的数据丢失了怎么办?
丢失分为三种:左侧、中间以及右侧丢失,后两种丢失都可以变为左侧丢失,因此只对左侧丢失做分析
答:假设发送方发送的序号为1001~2000、2001~3000、3001~4000、4001~5000。
①. 如果现在发送方在发送时,1001~2000的数据丢失了,而2000后的数据接收方正常接收。
这里需要注意一点:那就是发送方发过来的起始序号必须和接收方的确认序号是完全相同的。接收方的确认序号为1001,那么发送方发过来数据的起始序号必须为1001,如果1001~2000的数据丢失了,后续所有接收方收到的报文的确认序号都为1001,发送方在接收接收方的应答时,就还是从1001序号开始发送报文,如果发送方收到了多个相同确认序号,就会触发快重传,否则就是慢重传。
再来复习一下确认序号的定义:假设确认序号为x,告知对方,前x个序号已经被成功接收,下一次从x+1开始的序号发送数据。
上述情况,如果1001~2000的数据接收成功,那么接收方的确认序号会被重置为seq = 2000+1 = 2001,作为应答传给发送方,告知前2001个序号接收成功,下一个数据从2001序号开始,但是如果接收方接收失败,后续收到的报文的起始序号和当前接收方的确认序号不一致,那么接收方会以1001作为确认序号来应答。此时滑动窗口的大小不会更新!
②. 如果1001~2000数据的应答丢失,发送方收到了3001的确认序号,说明3001序号之前的数据已经接收完毕,此时可以更新滑动窗口的大小了,更新到3001序号处。
6. 拥塞控制
6.1 相关概念
拥塞窗口(cwnd):决定了发送端发送缓冲区滑动窗口的大小
滑动窗口大小 = min(拥塞窗口,对端接收缓冲区剩余空间)
注:网络情况是实时变化的,这决定了拥塞窗口也是实时更正的,拥塞窗口大,客户端的滑动窗口可能越大,能够发送的数据越多。
ssthresh:慢启动阈值
网络拥塞:在TCP网络通信过程中,出现大面积的丢包问题。
6.2 拥塞控制策略
具体方式:
1. 慢启动阶段
拥塞窗口指数增长,开始增长慢,探测网络情况,后续增长快,尽快占用带宽
2. 拥塞避免阶段
当拥塞窗口超过慢增长阈值时,开始线性增长,避免过快增长导致出现网络拥塞
3. 小面积丢包触发快/慢重传
当发生丢包时,接收方会发送重复的ACK,发送方可以快速重传丢失的数据包,
数据恢复后,拥塞窗口较小至原来的一半,并通过线性增长逐步恢复
4. 大面积丢包重新进入慢启动阶段
如果发生网络拥塞,慢开始阈值变为拥塞窗口的一半,拥塞窗口从1开始重新进入慢开始阶段
注:当发生网络拥塞时,此时客户端不能立即重传数据,因为成千上亿的用户如果同时重传,会导致网络负担进一步加大
7. 延时应答
概念:接收端在接收到对方报文,可以先等一下再答复,等待期间上层可能已经报这条报文处理完了,或者先前的报文处理完了,这样窗口的大小可能不变或者变大,再应答给发送端,这样发送端的窗口有概率会增大,发送更多数据
注:这个等待时间不会超过发送方的等待时间
相关文章:

Linux——UDP/TCP协议理论
1. UDP协议 1.1 UDP协议格式 系统内的UDP协议结构体: 注1:UDP协议的报头大小是确定的,为8字节 注2:可以通过报头中,UDP长度将UDP协议的报头和有效载荷分离,有效载荷将存储到接收缓冲区中等待上层解析。 注…...

Go语言爬虫系列教程(一) 爬虫基础入门
Go爬虫基础入门 1. 网络爬虫概念介绍 1.1 什么是网络爬虫 网络爬虫(Web Crawler),又称网页蜘蛛、网络机器人,是一种按照一定规则自动抓取互联网信息的程序或脚本。其核心功能是模拟人类浏览网页的行为,通过发送网络…...

PromptIDE提示词开发工具支持定向优化啦
老粉们都知道,PromptIDE 是一款专门解决 AI 提示词生成和优化的工具,让 AI 真正听懂你在说什么,生成更符合预期的结果! 我们这次更新主要争对提示词优化这一块,推出了不同提示词优化方向,贴近用户需求。 举…...
多返回值(Multiple Return Values)- 《Go语言实战指南》
Go 语言支持函数返回多个值,这一特性在实际开发中非常常见,尤其用于错误处理。 一、函数返回多个值的基本语法 func 函数名(参数列表) (返回值1类型, 返回值2类型, ...) {// 函数体return 值1, 值2, ... } 示例:计算商和余数 func divide(…...

致远OA人事标准模块功能简介【附应用包百度网盘下载地址,官方售价4W】
人事管理应用,围绕岗位配置、招聘管理、员工档案、入转调离、员工自助申报、数据信息管理等人力资源管理关键业务,构建全员可参与的人事工作协同平台,让人事从繁杂琐碎的事务中解脱出来,高质高效工作,让管理层清楚掌握…...

Python-简单网络编程 I
目录 一、UDP 网络程序1. 通信结构图2. Python 代码实现1)服务器端2)客户端 3. 注意 二、TCP 网络程序1. 通信结构图2. Python 代码实现1)服务器端2)客户端 3. 注意 三、文件下载1. PyCharm 程序传参1)图形化界面传参2…...

鸿蒙北向应用开发: deveco5.0 创建开源鸿蒙项目
本地已经安装deveco5.0 使用5.0创建开源鸿蒙项目 文件->新建->新建项目 直接创建空项目,一路默认 next 直接编译项目 直接连接开源鸿蒙5.0开发板编译会提示 compatibleSdkVersion and releaseType of the app do not match the apiVersion and releaseType on the dev…...
数据库故障排查指南:从入门到精通
1. 常见数据库故障类型 1.1 连接故障 数据库连接超时连接池耗尽网络连接中断认证失败1.2 性能故障 查询执行缓慢内存使用过高CPU使用率异常磁盘I/O瓶颈1.3 数据故障 数据不一致数据丢失数据损坏事务失败2. 故障排查流程 2.1 初步诊断 -- 检查数据库状态SHOW STATUS;SHOW PRO…...

国产linux系统(银河麒麟,统信uos)使用 PageOffice自定义Word模版中的数据区域
PageOffice 国产版 :支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel、兆芯、海光等)、ARM(飞腾、鲲鹏、麒麟等)、龙芯(Mips、LoogArch)芯片架构。 在实际的Wor…...

基于基金净值百分位的交易策略
策略来源:睿思量化小程序 基金净值百分位,是衡量当前基金净值在过去一段时间内的相对位置。以近一年为例,若某基金净值百分位为30%,意味着过去一年中有30%的时间基金净值低于当前值,70%的时间高于当前值。这一指标犹如…...

2025蓝桥杯JAVA编程题练习Day8
1. 路径 题目描述 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。 小蓝的图由 2021 个结点组成,依次编号 1 至 2021。 对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21࿰…...

通信安全堡垒:profinet转ethernet ip主网关提升冶炼安全与连接
作为钢铁冶炼生产线的安全检查员,我在此提交关于使用profinet转ethernetip网关前后对生产线连接及安全影响的检查报告。 使用profinet转ethernetip网关前的情况: 在未使用profinet转ethernetip网关之前,我们的EtherNet/IP测温仪和流量计与PR…...

DL00219-基于深度学习的水稻病害检测系统含源码
🌾 基于深度学习的水稻病害检测系统 — 智能农业的未来,守护农田的每一寸土地! 🚜 完整系统获取见文末 水稻病害检测,一直是农业领域的一大难题。传统的人工检测不仅耗时耗力,还容易因经验不足导致漏检或误…...
在24GB显存大小的GPU上运行27GB的Pytorch模型
在24GB显存大小的GPU上运行27GB的Pytorch模型 一.背景:显存不足时的破局之道1.1 大模型时代的显存困境1.2 CUDA统一内存的魔法二.性能测试数据深度解读关键发现:三.复现过程3.1 准备自定义分配器3.2 准备测试程序3.3 执行流程3.4 开始测试四.原理深度剖析4.1 统一内存的工作机…...
【数据机构】2. 线性表之“链表”
- 第 97 篇 - Date: 2025 - 05 - 16 Author: 郑龙浩/仟墨 【数据结构 2】 续上一篇 线性表之“顺序表” 文章目录 3 链表(用指针来首位相连)① 基本介绍② 分类 与 变量命名1 )分类:2 )大体介绍不同结构: ③ “单链表” 的实现:*…...

【51单片机中断】
目录 配置流程 1.在IE寄存器中开启总中断通道和需要的某中断通道 2.在TCON寄存器开启所用中断的触发方式 3.使用中断函数完成中断 4.若需要中断嵌套则在IP寄存器中配置 5.若需要使用串口的中断,则配置SCON寄存器 6.代码示例 配置流程 1.在IE寄存器中开启总…...

JavaSE基础语法之方法
方法 一、方法入门 1.方法定义 方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用。 2.方法的格式 修饰符 返回值类型 方法名( 形参列表 ){方法体代码(需要执行的功能代码) }示例: public static int sum ( int a ,…...

华为网路设备学习-22(路由器OSPF-LSA及特殊详解)
一、基本概念 OSPF协议的基本概念 OSPF是一种内部网关协议(IGP),主要用于在自治系统(AS)内部使路由器获得远端网络的路由信息。OSPF是一种链路状态路由协议,不直接传递路由表,而是通过交换链路…...

go-数据库基本操作
1. 配置数据库 package mainimport ("gorm.io/driver/mysql""gorm.io/gorm" ) #配置表结构 type User struct {ID int64 json:"id" gorm:"primary_key" // 主键ID自增长Username stringPassword string } #配置连接接信息 func…...
vue 中绑定样式 【style样式绑定】
style样式绑定 在 Vue 中,style 的绑定与 class 类似,也是通过 v-bind:style(或简写 :style)实现的,允许你动态地控制内联样式。Vue 对 style 做了非常智能的处理,支持对象、数组、字符串等多种语法&#…...
印刷业直角坐标型码垛机器人系统设计与应用研究
摘要 随着印刷行业自动化水平的提升,本文针对传统人工码垛存在的效率低、标准化程度不足等问题,提出基于直角坐标系的专用码垛机器人解决方案。重点阐述机械臂结构设计、运动控制系统及智能抓取装置三大核心模块,通过实际应用验证系统在速度、…...

Mysql存储过程(附案例)
文章目录 存储过程概述1、基本语法2、变量①、系统变量②、用户自定义变量③、局部变量 3、流程控制语句①、if语句②、参数③、case语句④、while语句⑤、repeat语句⑥、loop语句⑦、cursor游标⑧、handler 4、存储函数 存储过程概述 存储过程是事先经过编译并存储在数据…...

【Web应用】Vue 项目前端项目文件夹和文件介绍
文章目录 ⭐前言⭐一、文件夹介绍🌟1、.idea🌟2、bin🌟3、build🌟4、node_modules🌟5、public🌟6、src ⭐二、文件介绍🌟1、.editorconfig🌟2、.env.development、.env.production、…...

Stratix 10 FPGA DDR4 选型
文章目录 前言DDR3 和 DDR4 的区别Micron 8Gb DDR4 规格书详解Micron 8Gb DDR4 编码规则ConfigurationDDR4 寻址原理 Speed Grade内存的频率MT/s 与 MHz:更好的内存速度衡量指标为什么 DDR4 的核心频率与 I/O 总线频率的比例是 1:4 呢? 带宽 Altera FPGA…...
Rust 输出到命令行
Rust 输出到命令行 引言 Rust 是一门系统编程语言,以其高性能、内存安全、并发支持和零成本抽象等特性而闻名。在开发过程中,将 Rust 程序的输出传递到命令行是常见的需求。本文将详细介绍 Rust 输出到命令行的多种方法,帮助读者掌握这一技…...
费曼技巧及提高计划
费曼技巧及提高计划 一、什么是费曼技巧? 费曼技巧(Feynman Technique)由诺贝尔物理学奖得主理查德费曼提出,是一种通过“以教代学”来彻底理解复杂概念的学习方法。其核心逻辑是: “如果你不能简单解释一件事&#x…...
扩展:React 项目执行 yarn eject 后的 config 目录结构详解
扩展:React 项目执行 yarn eject 后的 config 目录结构详解 什么是 yarn eject?React 项目执行 yarn eject 后的 config 目录结构详解📁 config 目录结构各文件作用详解env.jsgetHttpsConfig.jsmodules.jspaths.jswebpack.config.jswebpackDe…...

CMU-15445(4)——PROJECT#1-BufferPoolManager-Task#2
PROJECT#1-BufferPoolManager Task #2 - Disk Scheduler 在前一节我实现了 TASK1 并通过了测试,在本节中,我将逐步实现 TASK2。 如上图,Page Table(页表)通过哈希表实现,用于跟踪当前存在于内存中的页&am…...

百度智能云千帆携手联想,共创MCP生态宇宙
5月7日,2025联想创新科技大会(Tech World)在上海世博中心举行,本届大会以“让AI成为创新生产力”为主题。会上,联想集团董事长兼CEO杨元庆展示了包括覆盖全场景的超级智能体矩阵,包括个人超级智能体、企业超…...
Python 中的 typing.ClassVar 详解
一、ClassVar 的定义和基本用途 ClassVar 是 typing 模块中提供的一种特殊类型,用于在类型注解中标记类变量(静态变量)。根据官方文档,使用 ClassVar[…] 注释的属性表示该属性只在类层面使用,不应在实例上赋值 例如&…...