TCP丢包,连接机制,滑动窗口解析

面向字节流


如何理解面向字节流?
发送缓冲区,我们将它当做char类型的数组,当发送时他们的发送序号就可以从他们的下标来获取,接受缓冲区也是char数组,再一个一个字节的向上层读取。


如何理解流动的概念

我们的报文中从没有提到标识数据大小,当接收缓冲区接收到10个报文时,将他们的报头分离,他们的数据无法分离就都同时存储在接受缓冲区,当上方一个字节一个字节向上读取,接收缓冲区又一个字节一个字节的读入,这就是流的概念

超时重传机制 丢包


1.数据丢了


客户端过一段时间会重新发送信息


2.应答丢了


服务端也是过一段时间重新发送信息


但是不是服务端可能收到了两条一样的报文?如何处理?
去重,根据报文的32位序号
所以发送方会将发送的报文暂时保存起来,那么保存在哪里呢?滑动窗口之中

超时时间是多少呢?
网络状态是变化的
超时太久发送:效率太低
超时时间过短:访问次数频繁
所以超时时间一定是浮动的,我们的超时时间是以500ms为单位的,例如第一次超时重传是1500模式、第二次就是2500,第三次就是4*500,超出一定的重传次数,我们就直接断开连接。
  


  

连接机制


我们的服务器内肯定有很多连接,我们就要对这些连接组织起来,先描述再组织,

struct links{
int start seq;
std::string src ip
std:string dst ip
,int srcport/dstport;
uint64 t timestamp,
int status;
int urgdataptr; 
struct links *next
}


连接时有状态变化的

#define set_syn 1
#define rec_syn 2

我们通过管理这些状态宏,将link结构体中的status替换成相对应的宏,就有连接的状态了

三次握手

为什么要进行三次握手?
a.以最小成本验证全双工,验证通信通道是否顺畅
建立连接是需要建立结构体管理的,是需要时间加空间的成本的,tcp协议双方地位是对等的
1.如果是一次握手,那么双方都无法确定是否可以通信,因为只发了一次SYN,此时还会引发SYN洪水
2.如果是两次握手呢,服务端知道了建立好了到客户端的链接,但是由于没有客户端的应答,无法确定客户端是否收到syn请求,但是此时客户端是知道自己到服务器的连接和服务器到客户端的连接都建立好了,此时服务端发出去应答+syn就会误以为连接建立,但此时的连接时无法保障的,可能浪费了服务端的资源+时间,造成双方无法对等
下文中还会提到
b.会同步序列号 简单是说
序号:比如ISN为1000,下一字节的数据序号就为1001;
确认序号:接收方成功接收的字节的数据序号的下一个。
假设客户端的ISNc为1000,服务端的ISNs为2000,三次握手的过程如下: ISNs为双方的起始报文序号
1.客户端SYN:SYN报文起始序号为1000
2.服务端SYN+ACK:SYN起始报文为2000,ACK中确认序号就为1000+1=1001,对客户端SYN的应答‘
3.客户端ACK:确认序号为2001,对服务端SYN做出应答
依次类推,因为服务端上一次发送确认序号为1001,此时客户发送1000字节,此时1000的字节数据序号就是1001~2000,ASK报头中确认序号就要为最后一个字节的数据序号+1,ACK的确认序号就是2001。


c.规定初始的滑动窗口大小(后文提及)


d.奇数次握手,保证了客户端要先建立连接,服务器才建立.
  
  
新理解:
四次握手+捎带应答
100:互相都保证了对方受到了我们建立连接的请求
也就是说少了哪一条信息,我们都能知道我们双方是否完成建立连接

四次挥手


三次握手是为了确定双方都建立好了连接,是为了确定性,那么四次挥手是不是也是为了确定性,为了双方地位对等
  
可不可以出现三次挥手呢?
    ACK+FIN
有可能,但三次握手不是主流,断开连接和建立连接是不一样的,建立连接是客户端主动建立连接,服务器被动接受,客户端一连接服务器,服务器就必须去连接,此时ACK+SYN就可以同时发送,。
断开连接是需要双方共同协商的,有可能当客户端发送FIN,但是服务器可你出现什么突发情况,不想去断开连接想继续向客户端发送数据,但是必须要回答,此时用ACK+FIN就不能完成这种场景。

四次挥手中的状态变化
  
CLOSE_WAIT:等待关闭,此时需要将通信套接字关闭
那么我们在断开连接中,不使用close函数,会发生什么?
服务器下会有非常多的CLOSE_WAIT,客户端接到ACK变成FIN_WAIT_2状态
  
当出现大量的CLOSE_WAIT状态,Linux系统网络应用越来越卡

主动断开的一方,会进入 TIME_WAIT 状态,这是一种等待的状态


让server主动断开,server进入TIME_WAIT?


server端的tcp会处于TIME_WAIT状态,等待一段时间后自动关闭,这个连接叫做尚未被彻底释放,也就是说此时端口号正在被使用,重启server,又要重新bind 端口号 ,此时就会报错:端口号正在被使用


client主动断开,为什么不会报bind端口号错误?
我们客户端绑定的端口是由操作系统提供的随机端口。

为什么要有Time_Wait?
许多教材中讲网络中会有尚未到达对方的报文,可是四次挥手都完成了,怎么还有报文未达到
有些历史报文可能是在网络传输过程中阻塞了,如在路由器中被阻塞。


那么在下一次建立连接时,未到达历史报文就发送到了服务器,那么就会对服务器接受报文造成影响。


Time_Wait就是在等历史报文进行消散,这样就能极大的减少对新连接的影响


为什么不是双方都进行Time_Wait?
主动断开连接的一定是有充足的时间等待报文全被发出去并达到,可是接受断开连接方就无法保证报文全部到达主动断开方
  
Time_Wait的时间是多少
2MSL
MSL:TCP报文的最大存活时间 centos版本是60s;
因为要让我们有可能接收到历史报文,还能有一次ACK的机会,所以是2倍

可是这样历史报文还是有可能对我们造成影响
a.双方采用随机序号,可是如果随机序号为1000,数据为3,发送给对方序号1003,可是对方如何对缓冲区进行管理,他又不知道报文数据的大小,那么怎么规划指针呢。


b.三次握手之中不仅仅是为了发送syn,随机序号是可以相互告知的,还会起始序号的协商,比如商量为1000,那么1003-1000=3,数据大小为3,就知道数据为3,将指针往后移动3位


c.即使旧的报文在网络中延迟很久后到达,也不会与新的连接混淆。这样序号发生冲突的概率变得更低了。

滑动窗口


并发的发送暂时不需要ACK的报文,从而提高效率
我们在上文中提到,发送报文是需要将报文保存起来的,方便丢失报文的时候重传,那么是存储在哪呢?
  
  

凡是在窗口范围内的报文可以直接发送,暂时不需要ACK
1.滑动窗口在哪里
滑动窗口是在发送缓冲区的一个区域
      
2.滑动窗口怎么理解
  
我们将缓冲区理解为一个char类型的数组,win_start和win_end中间的范围就叫滑动窗口。
滑动窗口的大小由谁决定?
目前:由对方接受缓冲区的接受能力决定
滑动窗口如何更新?
ACK会发送2个信息,一个是确认信号,另一个就是滑动窗口大小
newwin_start=确认信号
newwin_end=win_start+滑动窗口大小
最开始,我们还没有发送数据时,此时窗口大小应该为多大?
我们上文中提到三次握手会交换syn,和随机序号,其实还有初始的窗口大小。
3.滑动窗口向右移动时,滑动窗口会不会变小或变大?
当1-1000序号发送给对方的缓冲区,对方收到了返回ACK,返回序号为1001,但是接收缓冲区的数据未被读取,此时start指针向前移动,窗口大小就为3000。后文中还会提到因为拥塞控制使窗口变化,窗口大小是一直变化的。
  

滑动窗口会滑出去产生越界问题吗?
将发送缓冲区想象成环形队列


4.其他
  
报文丢失怎么办?
最左侧报文丢失
如果是最左侧报文丢失,例如1-1000丢失 那么1001-2000的ack 2001-3000的ack 3001-4000的ack的确认序号是多少呢?
我们重申一下概念:确认序号是在该序号之前的所有数据都收到了,那么如果1001-2000的ack是2001,这样的话我们2001前面的数据我们都收到了,但是1-1000的数据都丢了啊,所以1001-2000的ack只能是1001,2001-3000的ack肯定也不能是3001,所以只能是1001,我们把收到数个ack相同确定序号,此时立即对对应的报文进行补发,叫快重传。
我们之前提到在收到应答之前,报文会保存下来,保存在哪呢
暂时保存在发送缓冲区的滑动窗口中
当收到应答后,通过滑动窗口,删除对应的报文
但没收到应答,滑动窗口一定不会像右滑动


如果是最左侧ACK报文丢了呢?
最左侧丢了,只有最左侧丢了,最后的4001ACK能收到,我们之前的历史报文也能确定接收到


最中间报文丢失
中间报文的丢失,其实就是最左侧的报文丢失,左侧报文没丢,滑动窗口向右滑动,中间的报文变成最左侧报文,此时该中间报文的右边全是收到1001确认序号的ACK,引发快重传。


最右侧报文丢失
最右侧丢失,其实也是最左侧丢失,滑动窗口向右滑动,最右边又变成了最左侧。

快重传VS超时重传
快重传看起来更快,反应更灵敏,为什么又设计了超时重传?
快重传看起来很快很灵敏,但其实它需要收到3个相同的确认序号的ACK才能触发,而可能只收到2个相同的确认序号ACK,就无法触发了,而超时重传解决了这个问题一,他们两其实是互补的丢包解决方案

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

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

相关文章

前端开发设计模式——观察者模式

目录 一、定义和特点 1. 定义 2. 特点 二、实现方式 1. 使用 JavaScript 实现观察者模式的基本结构 2. 实际应用中的实现示例 三、使用场景 1. 事件处理 2. 数据绑定 3. 异步通信 4. 组件通信 四、优点 1. 解耦和灵活性 2. 实时响应和数据一致性 3. 提高代码的可…

少儿编程学习中的家庭支持:家长角色如何从监督到参与?

随着少儿编程教育的普及,越来越多的家庭开始意识到编程对孩子未来发展的重要性。编程不仅仅是一项技术技能,更是培养逻辑思维、解决问题能力和创新意识的有效途径。然而,如何在家庭中正确支持孩子的编程学习,对家长而言是一个新的…

EJB项目如何升级SpringCloud

记录某金融机构老项目重构升级为微服务过程1 如何从EJB架构拆分微服务 这个非常有趣的过程,整个过程耗时大致接近半年时光,需要考虑到重构升级保留原来的业务线,而且还要考虑后续的维护成本,保留现有的数据库表结构,…

基于SpringBoot的在线医疗问答平台

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

如何使用 Python 操作数据库

😀前言 在现代编程中,Python 的数据库操作已广泛应用于各类项目中,例如数据分析、Web 开发和数据持久化存储等。本文将介绍 Python 操作数据库的核心步骤,涉及数据库连接对象、游标对象的使用,以及常见的 SQL 数据操作…

夸克浏览器的用户反馈如何提交

夸克浏览器凭借其简洁的界面、强大的功能以及不断优化的用户体验,赢得了众多用户的青睐。然而,任何产品都不可能完美无缺,用户的反馈对于产品的持续改进至关重要。本文将详细介绍如何在夸克浏览器中高效提交用户反馈,帮助开发者更…

【移动应用开发】使用多媒体--通知/播放音频/视频

目录 一、具体步骤 二、运行截图 1. 开启通知权限 2. 播放音乐 3. 播放视频 三、源代码 1. activity_main.xml 2. activity_video_player.xml 3. activity_notification.xml 4. 一些配置 5. MainActivity 6. VideoPlayerActivity 7. NotificationActivity 8. And…

VulnHub-Brainpan1 靶机笔记

Brainpan1 靶机笔记 概述 靶机地址:https://vulnhub.com/entry/brainpan-1,51/#download 这台靶机是很好的缓冲区溢出漏洞利用的练习靶机,涉及到逆向和缓冲区溢出漏洞挖掘的一些知识。 一、nmap 扫描 1)端口扫描 nmap -sT --min-rate 1…

echarts实现 水库高程模拟图表

需求背景解决思路解决效果index.vue 需求背景 需要做一个水库高程模拟的图表&#xff0c;x轴是水平距离&#xff0c;y轴是高程&#xff0c;需要模拟改水库的形状 echarts 图表集链接 解决思路 配合ui切图&#xff0c;模拟水库形状 解决效果 index.vue <!--/*** author:…

【Linux探索学习】第九弹——Linux工具篇(四):项目自动化构建工具—make/Makefile

Linux笔记&#xff1a;https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在前面我们学习了如何用编译并执行&#xff0c;在现代软件开发中&#xff0c;构建一个项目涉及多个步骤&#xff0c;从编译源代码到链接库文件&a…

基于SpringBoot+Vue+MySQL的房屋租赁系统

系统展示 系统背景 随着城市化进程的加速和人口流动性的增加&#xff0c;房屋租赁市场逐渐成为城市生活的重要组成部分。然而&#xff0c;传统的房屋租赁方式存在诸多问题&#xff0c;如信息不对称、交易成本高、租赁关系不稳定等&#xff0c;这些问题严重影响了租赁市场的健康…

View三大机制(一):触摸机制(事件分发)

传递过程遵循如下顺序&#xff1a;Activity->Window->PhoneWindow->DecorView->RootView->ViewGroup->View View事件方法执行顺序:onTouchListener > onTouchEvent > onLongClickListener > onClickListener 主要由三个重要的方法共同完成的,只有Vi…

namespace 隔离实战

Docker简介 什么是虚拟化、容器化为什么要虚拟化、容器化?虚拟化实现 什么是虚拟化、容器化 物理机: 实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境&#xff0c;有时也称为“寄主”或“宿主”。 虚拟化: 是指通过虚拟化技术将…

Canvas 画布

文章目录 1. 初识1.1 认识画布1.2 兼容性1.3 上下文属性 2. 绘制2.1 绘制基本图形2.1.1 绘制矩形2.1.2 绘制圆形2.1.3 绘制直线2.1.4 绘制圆弧2.1.5 绘制贝塞尔二次曲线2.1.6 绘制贝塞尔三次曲线2.1.7 封装路径 2.2 颜色控制2.2.1 颜色设置2.2.2 线性渐变2.2.3 径向渐变2.2.4 圆…

XML解析小坑记录[正则表达式解析]

一、问题描述 在做 SSO 单点登录时( 认证中为CAS服务对接 )。在完成对用户ticket票根校验后&#xff0c;返回了用户信息有关 XML 数据片段&#xff0c;例如下&#xff1a; <cas:serviceResponse xmlns:cas"http://www.xxx.xx/xx/cas"><cas:authentication…

ffmpeg视频滤镜:网格-drawgrid

滤镜介绍 drawgrid 官网链接 》 FFmpeg Filters Documentation drawgrid会在视频上画一个网格。 滤镜使用 参数 x <string> ..FV.....T. set horizontal offset (default "0")y <string> ..FV.....T. set…

(50)MATLAB最优延迟迫零均衡器仿真测试与评估

文章目录 前言一、最优延迟迫零均衡器评估模型二、最优延迟迫零均衡器仿真代码1.代码如下&#xff1a;2.迫零均衡器函数zf_equalizer()的MATLAB源码 三、仿真结果画图1.不同权系数长度和延迟的迫零均衡器性能2. 不同权系数长度的迫零均衡器的最佳延迟 前言 对于预设均衡器延时…

用AI绘画工具提升创作效率,这款神器你一定不能错过!

在如今的创作领域&#xff0c;无论是插画师、设计师&#xff0c;还是内容创作者&#xff0c;都在寻找能够提升效率的工具&#xff0c;而AI绘画工具的诞生无疑是一场创意革命。通过AI技术的支持&#xff0c;我们不再需要耗费大量时间在绘制基础草图或反复调整细节上&#xff0c;…

为什么要使用Golang以及如何入门

什么是golang&#xff1f; Go是一种开放源代码的编程语言&#xff0c;于2009年首次发布&#xff0c;由Google的Rob Pike&#xff0c;Robert Griesemer和Ken Thompson开发。基于C的语法&#xff0c;它进行了一些更改和改进&#xff0c;以安全地管理内存使用&#xff0c;管理对象…

Oracle故障诊断(一线DBA必备技能)之ADRCI(四)

1. 题记&#xff1a; 本篇博文继续详细介绍一线DBA必备技能—Oracle DB故障诊断工具ADRCI。 2. 使用 ADRCI 进行故障诊断的步骤 1. 查看警报日志 警报日志是故障诊断的重要信息源&#xff0c;它记录了数据库启动、关闭、错误消息等关键事件。 首先启动 ADRCI。在操作系统命…