传输层-TCP 的安全机制和高效策略

news2024/12/23 17:53:23

可靠性:

之前我们在UDP中谈到了,UDP不可靠但是简单,TCP可靠但是也要做更多的工作,那这些工作具体是什么呢?接下来让我们详细了解一下。

确认应答机制(ACK机制)

序号:我们可以把TCP的发送缓冲去看作一个char sendbuffer[NUM] 的数组

每一个ACK都带有确认信号

超时重传机制

第二种情况收到了重复报文,可以通过序号来甄别。

  超时重传的时间限制该如何设定?

时间短 :会收到大量重复报文;时间长:client与server太用心效率低;可是短和长本来就不能固定的确定,所以超时重传的时间也不能是固定的,要根据当时的网络状况等因素来改变。

快重传VS 超时重传

快重传是一种网络传输协议中的算法,用于处理丢失的报文段。根据快重传算法的规定,当发送方连续收到三个重复确认时,即表示某个报文段可能丢失了,发送方会立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器到期。这样可以减少网络传输的延迟和拥塞问题的发生。

在一些实现中,快重传还会将拥塞窗口的值扩大一些,即等于ssthresh的三倍MSS。这是因为当发送方连续收到三个重复确认时,意味着有三个分组已经离开了网络,不再占用网络资源,而是停留在接收方的缓存中。因此,适当扩大拥塞窗口可以提高网络的传输效率。

快重传和超时重传相互合作,解决端到端的问题。

网络拥塞问题--拥塞控制

少量丢包时候,可以通过重传来解决,当发生大量丢包时候,就是网络的问题了,zheg=zhong故障叫做网络拥塞。 网络拥塞时候不能再进行重传了

TCP的拥塞控制算法 --慢启动机制。

慢启动是指在TCP协议中,当一个新的连接建立时,发送方会以较小的窗口大小开始传输数据,并随着时间的推移逐渐增加窗口大小来达到最大的传输速率。 慢启动的目的是为了在发送方和接收方之间建立起一个可靠的连接并适应网络的拥塞情况。

慢启动算法的原理是,发送方在开始传输数据时并不知道网络的实际情况,因此需要通过以较小的速度增加发送窗口的方式来试探网络的拥塞程度,并避免因发送过多数据而造成网络拥塞。

在慢启动阶段,发送方会不断增加发送窗口的大小,以加快数据的传输速度。当发送方收到确认消息时,窗口大小会翻倍,直到达到一个阈值为止。一旦窗口大小达到阈值,发送方就进入拥塞避免阶段,此时窗口大小会以较慢的速度增加。如果发生数据包丢失的情况,发送方会通过快速重传和快速恢复的机制来快速重新发送丢失的数据。

总之,慢启动是TCP协议中一种用于逐渐增加发送窗口大小以达到最大传输速率的算法,它能够有效地管理网络拥塞并提高传输性能

流量控制

 在进行流量控制时,我们是如何得知接收方的接受能力的?

三次握手过程中,TCP报头中有窗口大小前两次是不能携带报文数据的,但是可以携带缓冲区的大小(自己的),所以我们通过交换报文就可以得知对方的 接受能力 ,通过流量控制可以减少数据重传次数,提高TCP数据传输效率。

首先,我们来解决一个问题,帮助我们更好的理解流量控制

       TCP是如何做到全双工的?

TCP是有接收缓冲区和发送缓冲区的。

因为TCP有发送和接收缓冲区,所以clent和server就有了两对接收和发送缓冲区==》TCP全双工。

client发送速度不能太快,也不能太慢,--》引入流量控制。

什么决定server的接收能力?--------      接收缓冲区剩余空间大小。

滑动窗口 ---提高效率

滑动窗口机制允许向对方发送多个数据,但暂时都不需要确认,就可以立刻发送下一个数据。

滑动窗口的本质:

发送方可以一次性向对方发送推送数据的上限,滑动窗口必须有上限,这个上限由min(拥塞窗口,对方的接收能力)决定。滑动窗口的本质属性是指针或者下标。

它既想给对方推送数据,又想对方来得及接收。

滑动窗口的t模型

   滑动窗口必须向右移动吗?

不一定

  滑动窗口可以为0吗?

可以

    如果没有收到开始报文的应答,而是收到中间的?

可能有这种情况,可以通过序号和确认序号解决。win_start=收到的应答报文中的确认序号。win_end =win_start+min(拥塞窗口,对方接受能力)

 滑动窗口会不会越界?

不会,我们图上虽然是用一维数组模拟的,实际上内核中是通过一个环状结构,通过取模运算来管理滑动窗口的。

延迟应答

 如果接收数据的主机收到数据后立即进行ACK应答,此时返回的窗口可能比较小。

        假设对方接收端缓冲区剩余空间大小为1M,对方一次收到500K的数据后,如果立即进行ACK 应答,此时返回的窗口就是500K。但实际接收端处理数据的速度很快,10ms之内就将接收缓冲区中500K的数据消费掉了。在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。如果接收端稍微等一会再进行ACK应答,比如等待200ms再应答,那么这时返回的窗口大小就是1M。
 
需要注意的是,

1)延迟应答的目的不是为了保证可靠性,而是留出一点时间让接收缓冲区中的数据尽可能被上层应用层消费掉,此时在进行ACK响应的时候报告的窗口大小就可以更大,从而增大网络吞吐量,进而提高数据的传输效率。

2)此外,不是所有的数据包都可以延迟应答。

数量限制:每个N个包就应答一次。
时间限制:超过最大延迟时间就应答一次(这个时间不会导致误超时重传)。
延迟应答具体的数量和超时时间,依操作系统不同也有差异,一般N取2,超时时间取200ms。

捎带应答

捎带应答其实是TCP通信时最常规的一种方式,就好比主机A给主机B发送了一条消息,当主机B收到这条消息后需要对其进行ACK应答,但如果主机B此时正好也要给主机A发生消息,此时这个ACK就可以搭顺风车,而不用单独发送一个ACK应答,此时主机B发送的这个报文既发送了数据,又完成了对收到数据的响应,这就叫做捎带应答。

捎带应答最直观的角度实际也是发送数据的效率,此时双方通信时就可以不用再发送单纯的确认报文了。

此外,由于捎带应答的报文携带了有效数据,因此对方收到该报文后会对其进行响应,当收到这个响应报文时不仅能够确保发送的数据被对方可靠的收到了,同时也能确保捎带的ACK应答也被对方可靠的收到了。

面向字节流
 

当创建一个TCP的socket时,同时在内核中会创建一个发送缓冲区和一个接收缓冲区。

调用write函数就可以将数据写入发送缓冲区中,此时write函数就可以进行返回了,接下来发送缓冲区当中的数据就是由TCP自行进行发送的。
如果发送的字节数太长,TCP会将其拆分成多个数据包发出。如果发送的字节数太短,TCP可能会先将其留在发送缓冲区当中,等到合适的时机再进行发送。
接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区,可以通过调用read函数来读取接收缓冲区当中的数据。
而调用read函数读取接收缓冲区中的数据时,也可以按任意字节数进行读取。
由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:

写100个字节数据时,可以调用一次write写100字节,也可以调用100次write,每次写一个字节。
读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read100个字节,也可以一次read一个字节,重复100次。
实际对于TCP来说,它并不关心发送缓冲区当中的是什么数据,在TCP看来这些只是一个个的字节数据,它的任务就是将这些数据准确无误的发送到对方的接收缓冲区当中就行了,而至于如何解释这些数据完全由上层应用来决定,这就叫做面向字节流。

粘包问题
 

什么是粘包?

首先要明确,粘包问题中的“”,是指的应用层的数据包
在TCP的协议头中,没有如同UDP一样的“报文长度”这样的字段。
站在传输层的角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区中。但站在应用层的角度,看到的只是一串连续的字节数据。那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个完整的应用层数据包。

 

如何解决粘包问题

要解决粘包问题,本质就是要明确报文和报文之间的边界

对于定长的包,保证每次都按固定大小读取即可。
对于变长的包,可以在报头的位置,约定一个包总长度的字段,从而就知道了包的结束位置。比如HTTP报头当中就包含Content-Length属性,表示正文的长度。
对于变长的包,还可以在包和包之间使用明确的分隔符。因为应用层协议是程序员自己来定的,只要保证分隔符不和正文冲突即可。  

TCP异常情况
 

进程终止

当客户端正常访问服务器时,如果客户端进程突然崩溃了,此时建立好的连接会怎么样?

        

        当一个进程退出时,该进程曾经打开的文件描述符都会自动关闭,因此当客户端进程退

        时,相当于自动调用了close函数关闭了对应的文件描述符,此时双方操作系统在底层会正

        常完成四次挥手,然后释放对应的连接资源。也就是说,进程终止时会释放文件描述符

        TCP底层仍然可以发送FIN,和进程正常退出没有区别。

机器重启

当客户端正常访问服务器时,如果将客户端主机重启,此时建立好的连接会怎么样?

当我们选择重启主机时,操作系统会先杀掉所有进程然后再进行关机重启,因此机器重启和进程终止的情况是一样的,此时双方操作系统也会正常完成四次挥手,然后释放对应的连接资源。

机器掉电/网线断开

当客户端正常访问服务器时,如果将客户端突然掉线了,此时建立好的连接会怎么样?

当客户端掉线后,服务器端在短时间内无法知道客户端掉线了,因此在服务器端会维持与客户端建立的连接,但这个连接也不会一直维持,因为TCP是有保活策略的。

服务器会定期客户端客户端的存在状况,检查对方是否在线,如果连续多次都没有收到ACK应答,此时服务器就会关闭这条连接。
此外,客户端也可能会定期向服务器“报平安”,如果服务器长时间没有收到客户端的消息,此时服务器也会将对应的连接关闭。
其中服务器定期询问客户端的存在状态的做法,叫做基于保活定时器的一种心跳机制,是由TCP实现的。此外,应用层的某些协议,也有一些类似的检测机制,例如基于长连接的HTTP,也会定期检测对方的存在状态。

TCP小结
TCP协议这么复杂就是因为TCP既要保证可靠性,同时又尽可能的提高性能。

可靠性:

检验和;序列号;确认应答;超时重传;连接管理;流量控制;拥塞控制。
 

提高性能:

滑动窗口;快速重传;延迟应答;捎带应答。
需要注意的是,TCP的这些机制有些能够通过TCP报头体现出来的,但还有一些是通过代码逻辑体现出来的。

 

 

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

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

相关文章

Qt配置使用MSVC编译器

Qt配置使用MSVC编译器_qt msvc-CSDN博客注意:Qt支持的MSVC就是2017和2015,所以vs也要下载2017,不要直接用最新的,安装路径都用默认的。程序运行失败时可以尝试windeployqt拷贝库文件到本地,然后有可能就能运行了。VS官网下载Visua…

SOLIDWORKS工程图自动零件序号的极致体验

在装配体工程图中零件序号的标注要求不能漏标、要和明细表项目相对应、位置适当并且要按序排列。 这些要求看似简单,但是却需要极大的精力去完成。当然在SOLIDWORKS中这些问题都被很好的解决了,这也是本次分享的内容。 自动序号标注 1) 在进行尺寸标注前…

内网父子项目pom依赖依赖导入出现

这是拉下来两个独立的项目,子项目依赖父项目 我就把父项目install maven仓库中 再加载子项目 在子项目中就出现了有父项目导入类的提示但无论如何也导入不了该类 最后找错 我把本地父项目 install在maven仓库中删了 让子项目自动加载 就根据pom配置加载到内网仓库…

初始化一个 vite + vue 项目

创建项目 首先使用以下命令创建一个vite项目 npm create vite然后根据提示命令 cd 到刚创建的项目目录下,使用npm install安装所需要的依赖包,再使用npm run dev即可启动项目 配置 vite.config.js 添加process.env配置,如果下面 vue-route…

a_bogus 音 算法还原大赏

a_bogus算法还原大赏 hello,大家好呀,我是你的好兄弟,[星云牛马],花了几天时间算法还原了这个参数的加密过程,一起看看吧,记得加入我们的学习群:529528142 天才第一步,F12你会不&am…

jframe生成柱状图片+图片垂直合并+钉钉机器人推送

需求: 后端根据数据自动生成2个图片,然后把两张图片合并成一张图片,再发到钉钉群里,涉及到定时生成和推送,当时我们测试同事说他们写定时脚本放到服务器上,然后让我提供生成图片的方法和钉钉机器人的逻辑 天…

rhcsa5(日志、维护准确时间)

分析和存储日志 许多系统都以文本文件的方式记录事件日志,而这些文件保存在/var/log目录中。 在红帽中有systemd-journald和rsyslog服务管理日志进程。systemd-journald服务是操作系统事件日志架构的核心,包括内核、引导过程早期阶段的输出、守护进程启动…

第16章_多版本并发控制MVCC

1. 什么是MVCC MVCC ( Multiversion Concurrency Control ),多版本并发控制。顾名思义, MVCC 是通过数据行的多个版本管理来实现数据库的 并发控制 。这项技术使得在 InnoDB 的事务隔离级别下执行 一致性读 操作有了保证。换…

计算机毕业设计 基于SSM的问卷调查管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

孙哥Spring源码第20集

第20集 refresh()-invokeBeanFactoryPostProcessor 四-处理Configuration下的Bean生成代理对象 【视频来源于:B站up主孙帅suns Spring源码视频】【微信号:suns45】 1、二行InvokeBeanFactoryPostProcessors的作用 registryProcessors:处理的…

c语言逻辑思维

c语言逻辑思维 1.如何问问题? 有甲、乙两人,其中,甲只说假话,而不说真话;乙则是只说真话,不说假话。但是,他们两个人在回答别人的问题时,只通过点头与摇头来表示,不讲话。有一天,一…

怎么压缩pdf文件大小?详细压缩步骤

怎么压缩pdf文件大小?在日常的工作和学习中,我们频繁地处理PDF文件。然而,有时候这些文件的大小可能会非常庞大,这给我们带来了一系列的问题。首先,它们占用了大量的存储空间,使得我们的设备变得拥挤不堪。…

const int* , const int * const, int * const之间的区别

const int * p、int * const p 和 const int * const p 是指针声明中的三种常见形式,它们之间有以下区别: const int * p: 这表示 p 是一个指向常量整数的指针。指针 p 是可变的(mutable pointer),可以改变它所指向的对…

小白备战大厂算法笔试(四)——哈希表

文章目录 哈希表常用操作简单实现冲突与扩容链式地址开放寻址线性探测多次哈希 哈希表 哈希表,又称散列表,其通过建立键 key 与值 value 之间的映射,实现高效的元素查询。具体而言,我们向哈希表输入一个键 key ,则可以…

基于Java+SpringBoot+Vue摄影分享网站的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

JAVA怎么进行内存管理? - 易智编译EaseEditing

Java使用自动内存管理系统,主要通过垃圾回收器(Garbage Collector)来进行内存管理。这意味着开发人员不需要手动分配或释放内存,而是让垃圾回收器来处理不再使用的对象的内存释放。以下是关于Java内存管理的一些重要概念和建议&am…

SpringCloud Alibaba(2021.0.1版本)微服务-OpenFeign以及相关组件使用(保姆级教程)

💻目录 前言一、简绍二、代码实现1、搭建服务模块1.1、建立父包1.2、建立两个子包(service-order、service-product)1.3、添加util 工具类 2、添加maven依赖和yml配置文件2.1、springcloud-test父包配置2.2、服务模块配置2.2.1、service-orde…

Tailwind 练手项目

Tailwind 练手项目 用到的技巧 Tailwind CSS 速成 应该都提过了,我不记得这里有什么特别新的知识 整体完成图大概这样: 一个纯静态页面,没有做 JS 之类的特效,不过做了移动端适配,说实话我写到一半的时候改了不少………

【PTA】浙软2020年上机题目自测

个人学习记录,代码难免不尽人意。 在PTA买了浙软2020年的保研上机真题时光机做了做,20年的明显要比19年的难一些,我用了差不多2小时多一点做完了,最后得分90分,在当年排名26左右。下面是4道题和我的做法 7-1 Standard…

YOLO-NAS | YOLO新高度,引入NAS,出于YOLOv8而优于YOLOv8

编辑 | Happy 首发 | AIWalker 链接 | https://mp.weixin.qq.com/s/FsWSRguAn2WZKtmPhMbc6g 亮点在哪里? 参考QARepVGG,该方案引入了QSP与QCI模块以同时利用重参数与8-bit量化的优化; 该方案采用 AutoNAC搜索最优尺寸、每个stage的结构&#…