TCP如何保证服务的可靠性

TCP如何保证服务的可靠性

  • 确认应答
  • 超时重传
  • 流量控制
    • 滑动窗口机制概述
    • 发送窗口和接收窗口的工作原理
    • 几种滑动窗口协议
      • 1比特滑动窗口协议(停等协议)
      • 后退n协议
      • 选择重传协议
    • 采用滑动窗口的问题(死锁可能,糊涂窗口综合征)
      • 死锁
        • 如何解决死锁问题
      • 糊涂窗口综合症
      • 如何解决糊涂窗口综合征?
  • 拥塞控制
    • 为什么需要拥塞控制
    • 拥塞窗口
    • 拥塞控制算法
      • 慢启动与拥塞避免(TCP Tahoe版本)
      • 快速重传和快速恢复(TCP Reno版本)
  • 拥塞控制和流量控制的区别

TCP保证可靠性一般有以下几种方法:
(1)确认应答:ACK和序列号
(2)超时重传:发送数据包在一定的时间周期内没有收到相应的ACK,等待一定的时间,超时之后就认为这个数据包丢失,就会重新发送
(3)流量控制:控制发送方发送窗口的大小来实现流量控制
(4)拥塞控制:控制传输上流量

确认应答

TCP通过ACK实现可靠的数据传输。当发送端将数据发出之后会等待对端的确认应答,如果有确认应答,说明数据已经成功到达,如果没有,那么数据有可能丢失了,发送端就会进行重发。未收到确认应答也并不意味着数据一定丢失,有时也有可能是因为数据收到,但是ACK却在传输的途中丢了。因此这种情况也会导致发送端因没有及时收到ACK,而认为数据没有到达目的地,从而进行重传。

确认应答有时可能会延时到达,此时发送端会误认为数据丢失,所以会反复触发重传。因此接受主机就会反复接收到相同的数据。为此就必须要引入一种机制,使其能够识别是否已经接受数据,又能判断是否需要接受。序列号是按照顺序给发送数据的每一个字节都标上号码的编号。接收端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接受的序号作为确认应答返送回去。就这样,通过序列号和确认应答号,TCP可以实现可靠传输。

超时重传

在讨论超时重传之前,我们需要了解RTT和RTO:

  • RTT(Round Trip Time):一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值。
  • RTO(Retransmission Time Out):重传超时时间,即从数据发送时刻算起,超过这个重传超时时间便执行重传。

RTT和RTO 的关系是:由于网络波动的不确定性,每个RTT都是动态变化的,所以RTO也应随着RTT动态变化。

超时重传指的是如果在收到ACK之前,定时器到期,协议栈就会认为这个片段丢失,需要重新传送数据。这个等待时间即为RTO,其开始是一个预设的值(Linux 规定为1s),随着通讯的变化以及时间的推移,这个定时器的溢出值也应随着RTT动态变化,有很多算法计算RTO。

流量控制

如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。

所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。

滑动窗口机制概述

滑动窗口技术通过动态改变窗口大小来调节两台主机间数据传输,相互连接的主机间存在两个滑动窗口:一个用于接收数据,另一个用于发送数据。根据接收端的接收情况,动态去调整窗口大小,然后来控制发送端的数据流量。

  • 发送窗口:在任意时刻,发送方都维持一组连续的允许发送的帧的序号,称为发送窗口。
  • 接收窗口:接收窗口用来对发送方进行流量控制,而发送窗口的大小 W 代表在还没有收到对方确认信息的情况下发送方最多还可以发送多少个数据帧。

发送窗口和接收窗口的工作原理

在发送端,每收到一个确认帧,发送窗口就向前滑动一个帧的位置,当发送窗口内没有可以发送的帧(即窗口内全部是已发送,但未接收到确认的帧),发送方就会停止发送,直到收到接收方发送的确认帧使窗口移动,窗口内有可以发送的帧,之后才开始继续发送。

在接收端,接收窗口是为了控制可以接受哪些数据帧而不可以接收哪些帧。在接收方只有当收到的数据帧的序号落入接收窗口内才允许将该数据帧收下。若接收到的数据帧落在了接收窗口之外,则一律将其丢弃。
在这里插入图片描述

几种滑动窗口协议

1比特滑动窗口协议(停等协议)

当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停等协议(stop-and-wait)。该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。

后退n协议

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议。

后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。发送方在每发送完一个数据帧时都要设置超时定时器。只要在所设置的超时时间内仍未收到确认帧,就要重发相应的数据帧及其后的N帧。同时,接收方若发现错误帧就不再接收后续的帧。

在这里插入图片描述

后退n协议一方面因连续发送数据帧而提高了效率,但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。

选择重传协议

在后退n协议中,接收方若发现错误帧就不再接收后续的帧,即使是正确到达的帧,这显然是一种浪费。

另一种效率更高的策略是当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层。这种方法称为选择重发(SELECTICE REPEAT),其工作过程如图所示。显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间。
在这里插入图片描述

采用滑动窗口的问题(死锁可能,糊涂窗口综合征)

死锁

发送者会根据收到的报文段接收窗口的值调整自己的发送窗口。当接收方接收缓存满时就发送给发送方零窗口通知,告诉发送方停止发送。假设过一段时间接收方调整接收窗口为100,而此报文段在传送过程中丢失,这就导致发送方等待接收方的非零窗口通知,而接收方在等待发送方的数据。这样就导致了死锁。

如何解决死锁问题

为了防止这种情况,TCP为每个连接设置一个持续计时器。TCP连接的一方收到零窗口通知后,就启动计时器,设置的时间到期后它会发送一个探测报文段。如果此时返回的仍然是零窗口,则重新设定计时器。如果窗口不是零,那么死锁的僵局就可以被打破了。

糊涂窗口综合症

这个问题可以归结为小包的问题,就是由于发送端和接收端上的处理不一致,导致网络上产生很多的小包。

对于接收端来讲,如果接收很慢,一次接收1个字节或者几个字节,这个时候接收端缓冲区很快就会被填满,然后窗口通告为0字节,这个时候发送端停止发送,应用程序收上去1个字节后,发出窗口通告为1字节,发送方收到通告之后,发出1个字节的数据,这样周而复始,传输效率会非常低。同时如果发送端程序一次发送一个字节,虽然窗口足够大,但是发送仍是一个字节一个字节的传输,效率很低

如何解决糊涂窗口综合征?

发送窗口为0时,应用程序有收上去数据,但是并不立即回复发送窗口为1的通告,而是等待窗口大小满足一定的条件之后,如能够接收一个最大报文或者缓冲区的一半,再来发送窗口通告,这样就不会产生小报文。

拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞。

为什么需要拥塞控制

TCP通过滑动窗口来做流量控制,但是TCP觉得这还不够,因为滑动窗口需要依赖于连接的发送端和接收端,其并不知道网络中间发生了什么。具体一点,我们知道TCP通过一个timer采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。这是一个灾难。

所以,TCP不能忽略网络上发生的事情,而无脑地一个劲地重发数据,对网络造成更大的伤害。对此TCP的设计理念是:TCP不是一个自私的协议,当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了

拥塞窗口

发送方维持一个拥塞窗口cwnd的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。同时,发送方让自己的发送窗口等于拥塞窗口。只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减少一些,以减少注入到网络中的分组数。

拥塞控制算法

拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)快速重传,4)快速恢复。其中,慢启动与拥塞避免总是一起使用,并形成了TCP Tahoe版本的拥塞控制算法;快速重传和快速恢复总是一起使用,并形成了TCP Reno版本的拥塞控制算法。

慢启动与拥塞避免(TCP Tahoe版本)

如果发送方设置的超时计时器时限已到但还没有收到确认,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃。这时,TCP马上把拥塞窗口cwnd减少到1,并执行慢启动算法,同时把慢启动门限值ssthresh减半

慢启动算法:

  1. 发送方设置了超时计时器时限(即RTO)已到但还没有收到确认。
  2. 连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。
  3. 每当收到一个ACK,cwnd++; 呈线性上升
  4. 每当过了一个RTT,cwnd = cwnd*2; 呈指数上升
  5. 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”(后面会说这个算法)

拥塞避免算法

1。 收到一个ACK时,cwnd = cwnd + 1/cwnd
2. 当每过一个RTT时,cwnd = cwnd + 1

在这里插入图片描述

拥塞避免算法可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。很明显,是一个线性上升的算法。

快速重传和快速恢复(TCP Reno版本)

在使用快速重传和快速恢复算法时,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了FRR,就不会因为重传时要求的暂停被耽误。

快速重传算法

  1. 在收到3个重复确认时,开启重传
  2. 令sshthresh = cwnd,cwnd = cwnd /2。
  3. 进入快速恢复算法

快速恢复算法

  1. cwnd = sshthresh + 3(3的意思是确认有3个ACK被收到了)
  2. 如果再收到重复确认ACK,那么cwnd = cwnd +1。
  3. 当收到新的数据包的ACK时,把cwnd设置为第1步中的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了。
  4. 再次进入拥塞避免状态。
    在这里插入图片描述

拥塞控制和流量控制的区别

拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。

流量控制:指点对点通信量的控制,是端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

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

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

相关文章

ESP32 官方AT固件编译(从零开始环境搭建到编译完成全过程)

1、下载VMware免费版 https://download3.vmware.com/software/WKST-PLAYER-1702/VMware-player-full-17.0.2-21581411.exe 2、下载Ubuntu (ubuntu-22.04.2-desktop-amd64.iso)** https://releases.ubuntu.com/jammy/ubuntu-22.04.2-desktop-amd64.iso…

IDE/mingw下动态库(.dll和.a文件)的生成和部署使用(对比MSVC下.dll和.lib)

文章目录 概述问题的产生基于mingw的DLL动态库基于mingw的EXE可执行程序Makefile文件中使用Qt库的\*.a文件mingw下的*.a 文件 和 *.dll 到底谁起作用小插曲 mingw 生成的 \*.a文件到底是什么为啥mingw的dll可用以编译链接过程转换为lib引导文件 概述 本文介绍了 QtCreator mi…

AI编程常用工具 Jupyter Notebook

点击上方蓝色字体,选择“设为星标” 回复”云原生“获取基础架构实践 深度学习编程常用工具 我们先来看 4 个常用的编程工具:Sublime Text、Vim、Jupyter。虽然我介绍的是 Jupyter,但并不是要求你必须使用它,你也可以根据自己的喜…

PostgreSQL PG16 逻辑复制在STANDBY 上工作 (译)

开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共…

Mybatis-plus从入门到精通

1、什么是MyBatis-Plus MyBatis-Plus(简称MP)是一个基于MyBatis的增强工具,在MyBatis的基础上对其进行扩展,用于简化MyBatis操作,提高开发效率。它继承了MyBatis原生的所有特性,并且添加了一些额外的功能&…

前端随笔:HTML/CSS/JavaScript和Vue

前端随笔 1:HTML、JavaScript和Vue 最近因为工作需要,需要接触一些前端的东西。之前虽然大体上了解过HTML、CSS和JavaScript,也知道HTML定义了内容、CSS定义了样式、JavaScript定义了行为,但是却没有详细的学习过前端三件套的细节…

微服务入门---SpringCloud(一)

微服务入门---SpringCloud(一) 1.认识微服务1.0.学习目标1.1.单体架构1.2.分布式架构1.3.微服务1.4.SpringCloud1.5.总结 2.服务拆分和远程调用2.1.服务拆分原则2.2.服务拆分示例2.2.1.导入Sql语句2.2.2.导入demo工程 2.3.实现远程调用案例2.3.1.案例需求…

CoTracker跟踪器 - CoTracker: It is Better to Track Together

论文地址:https://arxiv.org/pdf/2307.07635v1.pdf 官方地址:https://co-tracker.github.io/ github地址:https://github.com/facebookresearch/co-tracker/tree/main 引言 在计算机视觉领域,光流估计是历史最久远的问题之一&a…

利用VBA制作一个转盘游戏之五:最终的游戏过程

【分享成果,随喜正能量】真正厉害的人,从来不说难听的话,因为人心不需要听真话,只需要听好听的话,所以学着做一个有温度且睿智的人。不相为谋,但我照样能心平气和,冷眼相待,我依旧可…

BGP的介绍

目录 BGP基础 BGP的发展历史 BGP在企业中的应用 距离矢量型协议和路径矢量型协议的区别 BGP的特征 1.可控性 2.可靠性 3.AS-BY-AS BGP的对等关系 BGP的数据包 1.open报文 2.Keepalive报文 3.Update报文 4.Notification 报文 5.Route-refresh报文 BGP的状态机 …

【暑期每日一练】 day7

目录 选择题 (1) 解析: (2) 解析: (3) 解析: (4) 解析: (5) 解析: 编程题 题一…

【深度学习中常见的优化器总结】SGD+Adagrad+RMSprop+Adam优化算法总结及代码实现

文章目录 一、SGD,随机梯度下降1.1、算法详解1)MBSGD(Mini-batch Stochastic Gradient Descent)2)动量法:momentum3)NAG(Nesterov accelerated gradient)4)权重衰减项(we…

使用 ChatGPT 进行研究的先进技术

在这篇文章中,您将探索改进您研究的先进技术。尤其, 分析和解释研究数据进行文献综述并找出研究差距废话不多说直接开始吧!!! 分析和解释研究数据 一家小企业主希望分析客户满意度数据以改善客户服务。他们使用包含 10…

【Lua学习笔记】Lua入门

文章目录 Lua变量数据类型变量声明其他表示 Lua语法判断逻辑判断(Lua很特殊,这个比较重要)短路判断 ifif else 循环whileforrepeat 迭代器泛型for迭代器无状态迭代器多状态的迭代器 Lua函数select方法 数组字符索引_G (不是教程&a…

opencv对相机进行畸变矫正,及矫正前后的坐标对应

文章目录 1.背景2.需求分析3.解决方案3.1.镜头畸变矫正3.2.知道矫正后的画面坐标(x, y),求其在原画面的坐标(x, y)3.2.知道原画面坐标(x1, y1),求其在矫正后的画面坐标(x2, y2) 4.效果5.代码 1.背景 目前有个项目,需要用到热成像相机。但是这…

k8s deployment(k8s经典版)|PetaExpress

Deployment是什么? Deployment是指在软件开发中将应用程序或系统部署到目标环境中的过程。它包括将代码编译、配置、打包并安装到目标服务器或设备上的步骤。k8s deployment是(k8s经典版)中用来管理发布的控制器,在开发的过程中使…

selenium等待的三种方式(详细)

1.强制等待 time.sleep(3) 这种方式会是操作强行等待3s才会进行下一步操作,但是这种放法,可能会延长测试的时间,如果元素在1s中出现,就会浪费2s的时间,并且这种放法单次有效,每次需要等待元素的操作都需要…

Python Geoplotlib 可视化地理数据的综合指南

Geoplotlib: Exploring the World with Python Python Geoplotlib 可视化地理数据的综合指南 Geoplotlib是一个强大的Python库,用于可视化地理数据。它提供了一种简单直观的方法来创建地图并在其上绘制地理数据。 Geoplotlib 建立在 matplotlib 和 numpy…

BUG分析以及BUG定位

一般来说bug大多数存在于3个模块: 1、前台界面,包括界面的显示,兼容性,数据提交的判断,页面的跳转等等,这些bug基本都是一眼可见的,不太需要定位,当然也不排除一些特殊情况&#xf…

【Koa】[NoSQL] Koa中相关介绍和使用Redis MongoDB增删改查

目录 NoSQL非关系型数据库关系型数据库(RMDB)介绍非关系型数据库(NoSQL)介绍Redis & MongoDB 在 Koa 中使用 Redis (了解)Redis 的安装和使用在 Koa 中连接 和 调用 Redis 在 Koa 中使用 MongoDBMongoDB 的安装MongoShell 操作…