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. 延时应答

概念:接收端在接收到对方报文,可以先等一下再答复,等待期间上层可能已经报这条报文处理完了,或者先前的报文处理完了,这样窗口的大小可能不变或者变大,再应答给发送端,这样发送端的窗口有概率会增大,发送更多数据

:这个等待时间不会超过发送方的等待时间

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

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

相关文章

考研复习全年规划

25考研以330分成功上岸。 备考期间,我深知学习规划的重要性,为大家精心整理了一份初试备考时间线任务规划,希望能为正在备考的同学们提供参考。如果你对如何规划学习路线仍感迷茫,不妨参考这份时间表,合理分配时间&…

PhpStudy | PhpStudy 环境配置 —— PhpStudy 目录结构 环境变量配置 · Windows 篇

🌟想了解这个工具的其它相关笔记?看看这个:[网安工具] 服务器环境配置工具 —— PhpStudy 使用手册 在前面的章节中,笔者详细介绍了如何在 Windows 和 Linux 系统中安装 PhpStudy,但可能会有崽崽在安装完成后发现依旧…

DDS(数据分发服务) 和 P2P(点对点网络) 的详细对比

1. 核心特性对比 维度 DDS P2P 实时性 微秒级延迟,支持硬实时(如自动驾驶) 毫秒至秒级,依赖网络环境(如文件传输) 架构 去中心化发布/订阅模型,节点自主发现 完全去中心化,节…

java中XML的使用

文章目录 什么是XML特点XML作用XML的编写语法基本语法特殊字符编写 约束XML的书写格式DTD文档schema文档属性命名空间XML命名空间的作用 解析XML的方法​​DOM解析XMLDOM介绍DOM解析包:org.w3c.dom常用接口DOM解析包的使用保存XML文件添加DOM节点修改/删除DOM节点 S…

Spring Boot异步任务失效的8大原因及解决方案

Spring Boot异步任务失效的8大原因及解决方案 摘要:在使用Spring Boot的@Async实现异步任务时,你是否遇到过异步不生效的问题?本文总结了8种常见的异步失效场景,并提供对应的解决方案,帮助你彻底解决异步任务失效的难题。 一、异步失效的常见场景 1. 未启用异步支持 ❌ …

QT6 源(104)篇一:阅读与注释QAction,其是窗体菜单栏与工具栏里的菜单项,先给出属性测试,再给出成员函数测试,最后给出信号函数的学习于举例测试

(1) (2) (3)接着给出成员函数测试 : (4) 给个信号函数的举例 : (5) 谢谢

visual studio生成动态库DLL

visual studio生成动态库DLL 创建动态库工程 注意 #include “pch.h” 要放在上面 完成后点击生成 创建一个控制台项目 设置项目附加目录为刚才创建的动态库工程Dll1: 配置附加库目录: 配置动态库的导入库(.lib):链…

matlab多智能体网络一致性研究

一个基于连续时间多智能体系统(Multi-Agent Systems, MAS)的一阶一致性协议的MATLAB仿真代码,包含网络拓扑建模、一致性协议设计和收敛性分析。代码支持固定拓扑和时变拓扑,适用于学术研究。 1. 基础模型与代码框架 (1) 网络拓扑…

【omnet++】omnet++6.0.3中调用python

版本: omnet 6.0.3 Ubuntu 20.04.6 LTS omnet的installguide中对ubuntu版本是有要求的,找到对应版本下载即可 先安装omnet再安装anaconda omnet 6.0.3安装 别在网上找教程了,官方的installguide手册是最好的。按照手册安装一些依赖包后 so…

【C++】 —— 笔试刷题day_29

一、排序子序列 题目解析 一个数组的连续子序列,如果这个子序列是非递增或者非递减的;这个连续的子序列就是排序子序列。 现在给定一个数组,然后然我们判断这个子序列可以划分成多少个排序子序列。 例如:1 2 3 2 2 1 可以划分成 …

UE RPG游戏开发练手 第二十七课 普通攻击2

UE RPG游戏开发练手 第二十七课 普通攻击2 1. 创建普通攻击的蒙太奇动画 2.打开4个蒙太奇动画,修改插槽为FullBody,修改动画速度 3.编辑动画蓝图,插入FullBody插槽让普通攻击动画得以播放 4. 编辑GA_LightAttack技能蓝图

MySQL——日志

undo log(回滚日志):引擎层生成的日志,实现了事务的原子性,用于事务回滚和MVCC。redo log(重做日志):引擎层生成的日志,实现了事务的持久性,用于非正常关闭的数据恢复。bin log(归档日志):Serve…

QML 动画控制、顺序动画与并行动画

目录 引言相关阅读基础属性说明工程结构示例代码解析示例1:手动控制动画(ControlledAnimation.qml)示例2:顺序动画(SequentialAnimationDemo.qml)示例3:并行动画(ParallelAnimationD…

PowerShell 实现 conda 懒加载

问题 执行命令conda init powershell会在 profile.ps1中添加conda初始化的命令。 即使用户不需要用到conda,也会初始化conda环境,拖慢PowerShell的启动速度。 解决方案 本文展示了如何实现conda的懒加载,默认不加载conda环境,只…

R语言学习--Day03--数据清洗技巧

在一般情况下,我们都是在数据分析的需求前提下去选择使用R语言。而实际上,数据分析里,百分之八十的工作,都是在数据清洗。并不只是我们平时会提到的异常值处理或者是整合格式,更多会涉及到将各种各样的数据整合&#x…

谷歌地图代理 | 使用 HTML 和矢量模式 API 更轻松地创建 Web 地图

在过去的一年里,谷歌对 Maps JavaScript API 进行了两项重要更新,以便更轻松地采用我们最新、最好的地图:HTML 地图和矢量模式 API。今天谷歌地图亚太区最大代理商之一的 Cloud Ace云一 为大家介绍一下更新的具体内容。 联系我们 - Cloud Ac…

WL-G4048 Multi-Port PCIe 4.0 Switch

系列文章目录 文章目录 系列文章目录《WL-G4048 Multi-Port PCIe 4.0 Switch数据手册》总结一、芯片介绍二、芯片规格介绍(一)功能指标(二)管理调试和监控(三)参考时钟(四)系统复位 …

召回11:地理位置召回、作者召回、缓存召回

GeoHash 召回 属于地理位置召回,用户可能对附近发生的事情感兴趣。GeoHash 是一种对经纬度的编码,地图上每个单位矩形的 GeoHash 的前几位是相同的,GeoHash 编码截取前几位后,将相同编码发布的内容按时间顺序(先是时间…

高效批量合并Word文档的工具介绍

软件介绍 本文介绍一款专门用于批量合并Word文档的工具,名为批量合并word工具。 使用方法与特点 如果需要将多个Word文档合并到一个Word文档中,就可以使用这款工具。使用前,需把要合并的Word文档都放在名为“word”的文件夹下。 该软件没有…

机器学习入门之KNN算法和交叉验证与超参数搜索(三)

机器学习入门之KNN算法和交叉验证与超参数搜索(三) 文章目录 机器学习入门之KNN算法和交叉验证与超参数搜索(三)一、KNN算法-分类1. 样本距离判断明可夫斯基距离 2. KNN 算法原理3. KNN 的缺点4. KNN 的 API5. 使用 sklearn 实现 …