【网络协议】TCP协议常用机制——延迟应答、捎带应答、面向字节流、异常处理,保姆级详解,建议收藏
💐个人主页:初晴~
📚相关专栏:计算机网络那些事
前几篇文章,博主带大家梳理了一下TCP协议的几个核心机制,比如保证可靠性的 确认应答、超时重传 机制,和提高传输效率的 滑动窗口及其相关优化机制。除此之外,TCP还有一些非常重要的核心机制,就让博主在本篇文章带着大家学习一下吧
一、延迟应答
TCP协议中的延时应答(Delayed Acknowledgment)机制是一种优化技术,旨在减少网络中的确认(ACK)消息数量,从而提高网络带宽利用率和减少网络拥塞。
试想一下,如果接收端在收到数据时就立马返回ACK应答可能会出现什么问题?
这时返回的窗口可能会比较小
- 假设接收端缓冲区为1M,⼀次收到了500K的数据,如果⽴刻应答,返回的窗⼝就是500K
- 但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了
- 在这种情况下,接收端处理还远没有达到⾃⼰的极限,即使窗⼝再放⼤⼀些, 也能处理过来
- 如果接收端稍微等⼀会再应答,⽐如等待200ms再应答,那么这个时候返回的窗⼝⼤⼩就是1M
主要原理是接收端在接收数据的时候,应用程序也在源源不断地消费接受缓冲区内的数据。
在收到数据时,先等一小会儿,缓冲区内的数据可能就会被消费而少掉很多,此时再返回给发送端 ACK时,返回的窗口大小就大概率会比立即返回更大。
而窗口越大,网络吞吐量就越大,传输效率也越高。因此延迟应答在一定程度上就能提高网络传输的效率。
但难道能一直延迟下去吗?延迟的时间过久也是会导致接受缓冲区爆满,引发丢包等一系列问题的。因此TCP会对延迟时间做出一些限制:
- 数量限制:每隔N个包就应答⼀次
- 时间限制:超过最⼤延迟时间就应答⼀次
这样就能很好地控制应答报文的返回密度,在不影响传输可靠性的条件下,尽可能提高网络传输的效率
二、捎带应答
在 延迟应答 的基础上,我们发现,实际网络通信中,大多数情况下都是“一问一答”的形式:
- ack ,是系统内核返回的,在收到请求后就立即返回ack
- 响应,是应用程序返回的,在代码中,根据请求计算得到响应,然后再返回给发送端
正常情况下,ack与响应 返回的时机不同,无法进行合并。
但别忘了,ack涉及“延时应答”机制,会让ack返回时间推迟。这一推迟,ack 就有机会等到 响应 报文生成的时候了,于是就可以再发送响应的时候,捎带上ack数据。
就好比说 客⼾端 给服务器说了 "How are you",服务器也会给客⼾端回⼀个 "Fine, thank you",而这个时候ack就等了一会儿,搭上顺风车,和服务器回应的 "Fine, thank you" 一起返回给客户端
还记得之前在 TCP协议“三次握手,四次挥手” 一文中我们研究过的四次挥手吗?
当时我们介绍过,ack是系统内核返回的,fin是应用程序返回的,理论上来说这俩发送时机并不同,是无法合并的。这也是“四次挥手”说法的由来。
但是,在延时应答的机制下,ack的返回时间可能会推迟,就有可能会和 FIN 合并,一起返回了。这时,“四次挥手” 就变成 “三次挥手” 了。
之所以ack可以和响应报文合并,是因为 ack 报文本身不需要载荷,只需在报头中将 ack字段设为“1”,接着设置好窗口大小、确认序号即可。这并不会与正常的响应报文产生冲突
三、面向字节流
- 调⽤write时,数据会先写⼊发送缓冲区中
- 如果发送的字节数太⻓,会被拆分成多个TCP的数据包发出
- 如果发送的字节数太短,就会先在发送缓冲区⾥等待,等到缓冲区⻓度差不多了,或者其他合适的时机发送出去
- 接收数据的时候,数据也是从⽹卡驱动程序到达内核的接收缓冲区
- 然后应⽤程序可以调⽤read从接收缓冲区拿数据
- 另⼀⽅⾯,TCP的⼀个连接,既有发送缓冲区,也有接收缓冲区
对于这⼀个连接,既可以读数据,也可以写数据。这个概念叫做 全双⼯
1、可以一次读写一个字节,分 100 次读写2、可以一次读写十个字节,分 10 次读写3、可以一次读写50个字节,分 2 次读写4、可以一次读写100个字节,一次读写完……
这样读写虽然十分自由,但也会带来一些问题。相比于面向数据报的传输方式,通过面向字节流的方式每次传输的界限没有那么分明了。容易导致粘包问题:
即应用层数据包在TCP的接收缓冲区内连成一片,粘在一起
站在应⽤层的⻆度, 看到的只是⼀串连续的字节数据。当应用程序需要读取接收缓冲区内的数据时,由于TCP是面向字节流的,因此缓冲区内数据怎么读都有可能。
可能会读出 a,a,a,b,b,b,c,c,c
也可能读出 aaa,bbb,ccc
还可能读出 aaabbbccc
……
这样肯定是不利于正确读取数据包意义的。想要解决粘包问题,关键就是要明确“包之间的边界”
- 方案一:指定分隔符
比如我们可以约定,请求响应都以 “\n” 结尾。这样在发送读取的时候都用 “\n” 作为分隔符,每当读写到 “\n” 时,就意味着一个数据包已经结束了,应用端就可以正常对这个数据包进行解析了。
不过,采用这种方案时一定要注意避免数据内容的正文中也会出现分隔符。比如采用ASCII中靠前的目前已不再使用的一些“控制字符”作为分隔符就比较合适。
常见的几种协议有xml、yml、json等,一般适用于文本类的数据的传输。
- 方案二:指定数据的长度
比如,约定在每个应用层数据包的开头2~4个字节,表示数据包的长度
UDP协议采用的就是这种方案。因此UDP传输是不会出现粘包问题的
四、异常情况处理
现实的网络通信中,不是每一次通信都能够正常完成“四次挥手”断开连接的,可能会遇到各种各样的异常情况。
1、进程崩溃
进程崩溃,听起来很严重,实际上操作系统会做好善后。当进程崩溃时,进程中的PCB就会被回收了,PCB中的⽂件描述符中的所有文件都会被操作系统自动关闭,仍然可以发送FIN。和正常关闭没有什么区别
2、主机关机(正常关机)
正常点击关机键关机时,操作系统会先终止所有进程,同时也会触发“四次挥手”机制。而这时就可能会出现两种情况:
(1)四次挥手完成后,关机才真正完成
这种情况不会有什么问题,通信会正常断开
(2)四次挥手还没有挥完,就已经关机完毕了
这时就有可能收不到 B 发来的 FIN 请求,也就无法像其返回ack,而 B 并不知道 A 已经关机了,接收不到 ack 就会导致四次挥手迟迟不能完成,通信也就无法正常断开了。
由于 B 接收不到 A 的ACK应答报文,等待一定时间就会触发“超时重传”机制重新发送 FIN报文。当 B 重传一定次数还没有响应时,就会主动断开连接(把保存的 A 的信息删掉了)。虽然过程有些曲折,但最终也能成功让通信断开
3、主机断电(异常关机)
(1)接收方断电
这时 A 给 B 发送数据,就不会再返回 ACK 了。
A 就会触发超时重传,当多次重传都没有得到 ACK 时,A就会尝试重置连接(reset)。如果重置操作也没有 ACK,A 就会单方面的释放连接(把 B 的信息删掉)
(2)发送方断电
A 发着发着没声了。在 B 的视角看来,并不确定 A 是终止了,还是说就是这段时间没有请求而已。此时,B 就会给 A 发送一个数据包,询问 A 是否还在。
如果发了探测报文后,A 返回了 ACK,就说明 A 只是暂时没有请求而已。但如果连续发了多个探测报文,A 都没有返回 ACK,就可以认为 A 是异常终止了。就会单方面释放连接。
TCP内置了⼀个保活定时器,会定时发送这样的探测报文。因为这样的报文是用来探测对方“生死”的,因此也会被称之为“心跳包”
4、网线断开
与主机断电类似。只不过是通信双方都感知不到对方的存在了。
- A 的视角:A 收不到 ACK ,触发多次超时重传,然后尝试重置连接,最后会单方面释放连接
- B的视角:A 忽然没有反应了。发多次心跳包也没有回应,最后也会单方面释放连接
这样,虽然过程曲折,但最后的结果还是成功让双方断开连接了。这样的处理还是能够让人接受的
总结
那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊
相关文章:

【网络协议】TCP协议常用机制——延迟应答、捎带应答、面向字节流、异常处理,保姆级详解,建议收藏
💐个人主页:初晴~ 📚相关专栏:计算机网络那些事 前几篇文章,博主带大家梳理了一下TCP协议的几个核心机制,比如保证可靠性的 确认应答、超时重传 机制,和提高传输效率的 滑动窗口及其相关优化机…...

财政部官宣: 国家奖学金,涨了!
财政部副部长郭婷婷10月12日在国新办新闻发布会上介绍,关于高校学生的资助,财政部将会同相关部门从奖优和助困两个方面,分两步来调整完善高校学生的资助政策—— 第一步是在2024年推出以下政策措施: 国家奖学金的奖励名额翻倍。…...

antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头
项目里遇到个需求,涉及到比较复杂的单元格合并 、嵌套表头、分组合并行、合并列等,并且数据列还是动态的,效果图如下: 可以分组设置【显示列】例如:当前组为【合同约定】,显示列为【合同节点】和【节点金额…...

一键安装与配置Stable Diffusion,轻松实现AI绘画
随着技术的迭代,目前 Stable Diffusion 已经能够生成非常艺术化的图片了,完全有赶超人类的架势,已经有不少工作被这类服务替代,比如制作一个 logo 图片,画一张虚拟老婆照片,画质堪比相机。 最新 Stable Di…...

模板和静态文件
模板和静态文件 1、templates模板2、静态文件2.1、static目录2.2、引用静态文件 1、templates模板 "templates"目录用于存放模板文件,通常是用于动态生成页面的文件。 在app01目录下创建templates文件夹,html文件均保存在templates中 在urls.p…...

Android Studio 打包aar丢失远程依赖问题解决
之前打包,使用的com.kezong.fat-aar,embed(‘XXXX’)的方式,可以使三方依赖打包在aar包里,在项目里直接使用 升级了Gradle:7.5后,打包就打包不起来了,一直报错ÿ…...

Chromium 搜索引擎功能浅析c++
地址栏输入:chrome://settings/searchEngines 可以看到 有百度等数据源,那么如何调整其顺序呢,此数据又存储在哪里呢? 1、浏览器初始化搜索引擎数据来源在 components\search_engines\prepopulated_engines.json // Copyright …...

DDoS攻击快速增长,如何在抗ddos防护中获得主动?
当下DDoS攻击规模不断突破上限。前段时间,中国首款3A《黑神话:悟空》也在一夜之内遭受到28万次攻击DDoS攻击,严重影响到全球玩家的游戏体验。Gcore发布的数据也显示了 DDoS攻击令人担忧的趋势,尤其是峰值攻击已增加到了令人震惊的…...

MongoDB 死锁 锁定问题
要查看 MongoDB 是否出现“锁死” (也就是所谓的 锁定问题,通常指长时间的锁定导致数据库操作无法正常进行),可以通过以下几种方法来检测数据库的锁定状态和锁定相关信息。 1. 使用 db.currentOp() 检查活动操作 MongoDB 提供了 db.currentOp() 命令来查…...

鸿蒙--商品列表
这里主要利用的是 List 组件 相关概念 Scroll:可滚动的容器组件,当子组件的布局尺寸超过父组件的视口时,内容可以滚动。List:列表包...

【Fargo】5:根据网络带宽动态调整发送速率
根据网络带宽动态调整发送速率 原理:这个简单实现的原理是 改变包的发送速率就可以改变发送码率了。例如1秒发1000个1KB 的包,带宽8Mbps,如果带宽是4Mbps,那么1秒发500个就够了。D:\XTRANS\thunderbolt\ayame\zhb-bifrost\player-only\worker\src\fargo\zhb_uv_udp_sender.…...

入门C语言:从原码、反码、补码到位运算
入门C语言:从原码、反码、补码到位运算 C语言作为一门底层编程语言,离不开对计算机硬件的深入理解。掌握整数的二进制表示法和位运算是深入学习C语言的基础。对于大一新生来说,理解原码、反码、补码与位运算这几个概念,将帮助你更…...

18770 差值最大
### 思路 为了找到两个数x和y使得x - y的值最大,并且x在y的右侧,我们可以使用以下方法: 1. 从右向左遍历数组,记录当前遍历到的最大值max_right。 2. 对于每个元素a[i],计算max_right - a[i],并更新最大差…...

【Flutter】合并多个流Stream
1.说明 无意间发现了一个好用的库rxdart,它为 Dart 的 Stream 添加了额外的功能。 2.功能 (1)合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意:如果dart文件中同时使用了getx,需要隐…...

【SQL学习笔记】
Pycharm社区版的页面中无database选项? 1、进入Setting-Pluggins窗口,输入database navigator 2、安装后,重启即可 MySQL 的架构共分为两层:Server 层和存储引擎层 1、Server 层负责建⽴连接、分析和执⾏ SQL 2、存储引擎层负…...

contact form 7设置方法与详细步骤
Contact Form 7(CF7)是WordPress中非常流行的表单插件,用于创建和管理网站上的联系表单。以下是Contact Form 7的设置方法与详细步骤: 一、安装Contact Form 7插件 从WordPress后台安装: 登录WordPress后台,进入“插件”菜单下…...

第170天:应急响应-战中溯源反制对抗上线CSGoby蚁剑Sqlmap等安全工具
目录 案例一:溯源反制-Webshell工具-Antsword 案例二:溯源反制-SQL注入工具-SQLMAP 案例三:溯源反制-漏洞扫描工具-Goby 案例四:溯源反制-远程控制工具-CobaltStrike 反制Server,爆破密码(通用&#x…...

5-容器管理工具Docker
├──5-容器管理工具Docker | ├──1-容器管理工具Docker | | ├──1-应用部署容器化演进之路 | | ├──2-容器技术涉及Linux内核关键技术 | | ├──3-Docker生态架构及部署 | | ├──4-使用容器运行Nginx及docker命令介绍 | | ├──5-容器镜像介…...

OCR+PDF解析配套前端工具开源详解!
目录 一、项目简介 TextIn为相关领域的前端开发提供了优秀的范本。 目前项目已在Github上开源! 二、性能特色 三、安装使用 安装依赖启动项目脚本命令项目结构 四、效果展示 面对日常生活和工作中常见的OCR识别、PDF解析、翻译、校对等场景,配套的…...

【操作系统】引导(Boot)电脑的奇妙开机过程
🌹😊🌹博客主页:【Hello_shuoCSDN博客】 ✨操作系统详见 【操作系统专项】 ✨C语言知识详见:【C语言专项】 目录 什么是操作系统的引导? 操作系统的引导(开机过程) Windows操作系…...

国产云桌面迁移对接信创AD域控方案
在前文《替换AD域时,网络准入场景如何迁移对接国产身份域管?》中,根据 AD 在企业中的应用程度,我们将企业分为了轻度、中度及深度三类微软 AD 用户。 轻度AD用户:仅部分应用对接 AD 。替换 AD 时,可能会直接…...

ESP32—C3实现DS18B20(温度传感器)检测温度(Arduino IED )
1源代码(DS18B20) #include <OneWire.h> // 引入OneWire库,用于与单总线设备通信 #include <DallasTemperature.h> // 引入DallasTemperature库,用于读取DS18B20温度传感器数据// 定义连接到DS18B20数据引脚的GPIO编…...

Linux系统中安装KenLM步骤及注意事项
一、前言: Kenlm模型:本项目基于Kenlm统计语言模型工具训练了中文NGram语言模型,结合规则方法、混淆集可以纠正中文拼写错误,方法速度快,扩展性强,效果一般 二、安装步骤: 1、安装依赖项 Ke…...

xss-labs靶场第六关测试报告
目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、注入点寻找 2、使用hackbar进行payload测试 3、绕过结果 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机:本机(127.0.0.1) 靶 机:本机(127.0.0.…...

传智杯 第六届—E
题目描述: leafee 最近爱上了 abb 型语句,比如“叠词词”、“恶心心”。 leafee 拿到了一个只含有小写字母的字符串,她想知道有多少个 "abb" 型的子序列? 定义: abb 型字符串满足以下条件: 字符…...

2024.10月12日--- SpringMVC异常处理
异常处理 SpringMVC处理异常的方式有三种,当然也可以使用AOP面向编程,自定义一个类进入切入。 第一种:使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver <!--SpringMVC提供的异常处理器类型:SimpleMappingE…...

边缘人工智能(Edge Intelligence)
边缘人工智能(Edge AI)是指在边缘设备上直接运行人工智能(AI)和机器学习(ML)算法的技术。机器学习是一个广泛的领域,近年来取得了巨大的进步。它所基于的原则是,计算机可以通过从数据…...

C++20主要特性
Concepts(概念): Concepts 是一种新的语言特性,允许程序员明确定义类型的要求,从而提高了模板代码的可读性和错误消息的质量。 template <typename T> concept Integral std::is_integral_v<T>;template…...

IterComp: 从模型图库中迭代合成感知反馈学习,用于文本到图像的生成
我们从多个模型中收集组成感知模型偏好,并采用迭代反馈学习方法,使基础扩散模型和奖励模型都能逐步自我完善。 我们提出了一种迭代反馈学习方法,通过多次迭代,使基础扩散模型和奖励模型逐步自我完善,从而以闭环方式增…...

6.Python 函数进阶(函数多返回值、函数多种传参方式、匿名函数)
一、函数多返回值 1、具体实现 def test_return():return 1, 2x, y test_return()print(x) print(y)输出结果 1 22、解析 按照返回值的顺序,用对应顺序的多个变量接收,变量之间用逗号(,)隔开 支持返回不同类型的数据 二、函…...