TCP协议的流量控制和拥塞控制
一开始,我总是容易把这2个概念搞混淆了,因此,为了加深理解,我写出来整理下思路。
一:流量控制
什么是流量控制,它涉及到哪些内容呢?
首先,我们看看一个最简单的tcp传输涉及到哪些东西
发送端,数据,网络,接收端(对端)
最基本的就是这4个对象。
流量控制是什么: 流量是什么?肯定就是数据。因为数据流动就形成了流量。
控制呢,控制谁?谁被控制?这就涉及到发送端和接收端了。这2端来进行“控制”和“被控制”。
正常情况下,发送端发送数据,接收端接收数据。就这么一个过程。2端也相安无事。
突然,发生了不正常情况,发送端发送数据加快了,接收端按照原先的情况接收数据就接收不过来,接收端缓冲区满了,不能在装多余的数据了,那多余的数据就会被丢弃,这样会导致发送端触发重发机制重发数据。所以必须进行控制。
流量控制就是:
如果发送端发送的数据过快,接收端来不及接收,那么分组数据就会丢失。为了避免这种数据丢失,就需要控制发送者的速度,使得接收者来得及接收,这就是流量控制。
为了控制发送者的速度,我们要怎么做呢?
TCP最开始是以1个段为单位进行数据发送,每发送一个段就进行一次确认应答处理。想想看,这样的传输方式有什么缺点呢,是不是传输的量少,传输效率就下降,且确认应答也会增多。
既然传输1个段有这些问题,那我一次能不能多传几个段呢?当然是可以的,这就引入了窗口的概念。多个段组成一个窗口进行连续发送。
前面我们讲数据超时重发时,说过序列号,就是对传送的数据按顺序进行编号。窗口就用到了这个序列号,利用序列号来进行分段编号。然后把分段组织起来变成一个窗口。
把数据分段编号,比如:
- 1-1000 为第一段
- 1001-2000 为第二段
- 2001-3000 为第三段
- 3001-4000 为第四段
- 4001-5000 为第五段
把数据进行了分段,这时候发送端发送一个段以后不必要一直等待确认应答,而是可以继续发送数据。而接收端确认时,不必每次确认,而是可以以更大的单位进行确认。
但是发送端也不能一直发送不进行确认,这样发送端不知道接收端是啥子情况。所以整理我们必须也控制一下,比如说我发送4个分段,就需要进行确认才发送新的数据。这4个分段就组成了一个窗口大小。
窗口大小:
就是指无需等待确认应答就可以继续发送数据的最大值
这个机制使用了大量缓冲区,通过对多个段同时确认应答。
接收端的窗口大小,发送端是怎么知道的?
1、建立连接时
接收端发送ACK确认时会告诉发送端,我接收端的窗口大小是多少。tcp里用rwnd表示(receiver window,接收端窗口)
2、建立连接后发送数据
接收方每次收到数据包后在发送确认报文时,同时告诉发送方自己的缓存区还剩余多少是空闲,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。
发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。
在TCP的首部中,有一个16位窗口字段,此字段就是用来存放窗口大小信息的
假如我们有如下分段数组需要发送:
- 1-1000 为第一段
- 1001-2000 为第二段
- 2001-3000 为第三段
- 3001-4000 为第四段
- 4001-5000 为第五段
- ... ...
|1-1000|1001-2000|2001-3000|3001-4000|4001-5000|50001-6000|6001-7000|70001-8000|... ...|
比如1001-5000 组成一个窗口(四个分段)进行数据发送,在这个窗口内的数据即使没有收到确认应答也可以发送出去。如果从该窗口发送的数据在传输中丢失,也需要进行重发。因此,发送端主机在等待应答号返回前,也必须在缓冲区中保留这部分数据。
在收到确认应答的情况下,可以将窗口位置滑动到确认应答号的位置。这样可以顺序的将多个分段同时发送以提高通信的效率和性能。这种机制就叫滑动窗口机制。当然这个窗口大小也是会根据接收端返回的应答窗口大小进行调整。这个就是流控制(流量控制)。
每次接收端返回一个确认号,比如2001,3001,4001,收到3个确认号,没有收到5001,那么接收端会重复发3次4001,发送端主机连续3次收到同一个确认应答,就会对其进行重发。这个机制比超时管理更有效,因此也称为快速重发控制。
二:拥塞控制
还是让我们首先来看看,一个最简单的tcp传输涉及到哪些东西
发送端,数据,网络,接收端(对端)
流量控制是针对发送端的,是接收端指示发送端使用多大的发送窗口。拥塞控制是针对网络的。他俩是不同的。
网络发生拥塞了,当然整个网络的传输速率就会下降了。其实网络里包含路由器,交换机,主机等多种网络设备。
当主机发送到网络的数据包数量超过了网络的承载能力时,就会发生拥塞。如果在继续大量发送,就可能造成网络崩溃。
方法一:
TCP的拥塞控制策略:
TCP处理拥塞策略一般基于3个阶段:慢开始、拥塞避免 和 拥塞检测。
慢开始:指数增大
慢开始:发送端从非常慢的传输速率开始,但是很快就把速率增大到一个阙值。当到达阙值门限后,数据的增长开始放慢。最后,只要一检测到拥塞,发送端就回到慢开始或者拥塞避免阶段。
慢开始:指数增大
慢开始算法的思想:即拥塞窗口cwnd从1个最大报文段的长度(MSS)开始。MSS的数值是在连接建立时来确定的。每当一个报文被确认,拥塞窗口就增大1个MSS。随后是2,4,8...,按指数规律增大。
以下说明这个指数增长的规律:
发送方从cwnd=1 MSS 开始。在第一个ACK到达后,拥塞窗口增加1,也就是说现在cwnd=2。此时发送2个报文段。当相应2个ACK到达后,对于每一个ACK,窗口大小增加1 MSS,这就表示现在cwnd=4。此时发送4个报文段。当4个ACK到达后,窗口大小又增加4,也就是cwnd=8。 依次类推...
但是慢开始也不能无限的增长下去。慢开始无限增大,cwnd也会变得很大,这样必然会造成网络拥塞,所以要有一个停止阶段。发送方有一个称为ssthresh(慢开始门限)的变量。 当以字节计算的窗口大小达到这个ssthresh值时,慢开始阶段结束,++并进入下一个阶段++ - 拥塞避免。
拥塞避免:加法增大
拥塞避免:加法增大
我们从慢开始算法开始,拥塞窗口大小按照指数规律增长。但是为了发生拥塞之前避免它,就必须使指数增长变慢。于是TCP又定义了另外一个算法,叫做拥塞避免(congestion avoidance),使cwnd的值按照加法规律增长,而不是按照指数规律增长。
当拥塞窗口的大小达到慢开始的门限时(ssthresh),慢开始阶段就停止了,这时,加法增加阶段就开始了。
加法增的算法思想:
每当一个整个窗口中的报文段被确认后,拥塞窗口大小才增加1。 一个窗口就是指在一个RTT期间传输的报文段的数量。换言之,这个增长是基于RTT的,而不是基于到达的ACK的数量。
加法增的算法规律:
- 1.开始时: cwnd = i
- 2.经过1 RTT后: cwnd = i + 1
- 3.经过2 RTT后: cwnd = i + 2
- 4.经过3 RTT后: cwnd = i + 3
在拥塞避免算法中,拥塞窗口的大小按照加法规律增长,直到检测到拥塞为止。
拥塞检测:乘法减小
那怎么才能检测到拥塞现象呢?
做法就是:让发送方重传一个报文段。
这是TCP做出的一个重要的假设,之所以要重传报文是为了恢复一个遗失的分组,而这个分组假设是因为某个路由器有太多的输入分组而不得不丢弃,也就是说,路由器或者网络已变得超载和拥塞了。
重传可以发生以下2中情况:
- 1.当RTO计时器超时
- 2.当收到了三个重复的ACK应答时
反正不管哪一种情况,门限值都要下降到一半(乘法减小)。
整个拥塞流程梳理下:
1)拥塞窗口cwnd初始化为1个报文段,慢开始门限初始值为16
2)执行慢开始算法,指数规律增长到第4轮,即cwnd=16=ssthresh,改为执行拥塞避免算法,拥塞窗口按线性规律增长
3)假定cwnd=24时,网络出现超时(拥塞),则更新后的ssthresh=12,cwnd重新设置为1,并执行慢开始算法。当cwnd=12=ssthresh时,改为执行拥塞避免算法
“拥塞避免”并非完全能够避免了阻塞,而是使网络比较不容易出现拥塞。
方法二:快速重传、快速恢复
在前面流量控制里讲过整个快速重传机制。 就是一个发送端的数据包丢失了,怎么才能快速识别出来已经丢失了呢? 而不是等待比较漫长的超时机制。 这个方法就是:发送端收到同一个确认包3次,就认为这个保丢失了。 这个机制就叫做快速重传机制。
根据上面的拥塞检测,快速重传后,慢启动门限阙值就要设置为拥塞窗口的一半。然后重新开始慢启动过程。
快速恢复(fast revovery):
当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半(为了预防网络发生拥塞)。但是接下去并不执行慢开始算法(a)而是拥塞避免算法。 这就是快速恢复算法。
(a)这里没有执行慢启动算法是因为:收到重复的ACK不仅仅告诉我们一个分组丢失了。由于接收端只有在收到另一个报文段时才会产生重复的ACK,而该报文段已经离开了网络并进入了接收方的缓冲区。也就是说,在收发两端仍然有数据流动,而我们不想执行慢开始算法来突然减少数据流。而是将cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,使cwnd缓慢增大。
快速恢复算法出现在4.3BSD Reno版本中
参考
TCP协议的流量控制和拥塞控制的更多相关文章
- [TCP/IP] TCP如何实现流量控制和拥塞控制
流量控制:数据的传送与接收过程当中很可能出现收方来不及接收的情况,这时就需要对发方进行控制,以免数据丢失.流量控制用于防止在端口阻塞的情况下丢帧,这种方法是当发送或接收缓冲区开始溢出时通过将阻塞信号发 ...
- TCP协议中是如何保证报文可靠传输的
1.什么是TCP的可靠传输 它向应用层提供的数据是无差错的.有序的.无丢失的,换言之就是:TCP最终递交给应用层的数据和发送者发送的数据是一模一样的. 2.TCP保证可靠传输的办法有哪些? TCP采用 ...
- socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...
- [转]socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题
Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...
- TCP具体解释(3):重传、流量控制、拥塞控制……
传输数据 在TCP的数据传送状态.非常多重要的机制保证了TCP的可靠性和强壮性.它们包括:使用序号.对收到的TCP报文段进行排序以及检測反复的数据:使用校验和来检測报文段的错误.使用确认和计时器来检測 ...
- TCP的流量控制与拥塞控制小结
概述 为了提高信道的利用率TCP协议不使用停止等待协议,而是使用连续ARQ协议,意思就是可以连续发出若干个分组然后等待确认,而不是发送一个分组就停止并等待该分组的确认.其中TCP的流量控制与拥塞控制是 ...
- TCP基础知识(三)重传、流量控制、拥塞控制
TCP详解(3):重传.流量控制.拥塞控制…… 数据传输 在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性.它们包括:使用序号,对收到的TCP报文段进行排序以及检测重复的数据:使用校 ...
- TCP的可靠传输(依赖流量控制、拥塞控制、连续ARQ)
TCP可靠性表现在它向应用层提供的数据是无差错,有序,无丢失,即递交的和发送的数据是一样的. 可靠性依赖于流量控制.拥塞控制.连续ARQ等技术 <TCP/IP详解>中的“分组”是不是就是报 ...
- 运输层7——TCP的流量控制和拥塞控制
目录 1. TCP的流量控制 2. TCP的拥塞控制 写在前面:本文章是针对<计算机网络第七版>的学习笔记 运输层1--运输层协议概述 运输层2--用户数据报协议UDP 运输层3--传输控 ...
- TCP 的三次握手和四次挥手,TCP 的流量控制和拥塞控制
70.TCP协议的三次握手与四次挥手70.1.TCP报文结构 1.源端口号:表示发送端端口号,字段长为16位. 2.目标端口号:表示接收端口号,字段长为16位. 3.序列号:表示发送数据的位置 ...
随机推荐
- [转帖]ES集群开启X-pack认证
https://www.cnblogs.com/jclty/p/12913996.html 1.下载 1 # wget https://artifacts.elastic.co/downloads/e ...
- 【转帖】SRE 高延迟问题的罪魁祸首 System.gc()
https://www.infoq.cn/article/lXTRgYb9ecVBu*72fT7O jstact -gccause pid 3000 30 01 案例一: 某日,支付平台的开发人员找到 ...
- [转帖]BIS出口管制新规说明会,进一步明确十大问题
https://zhuanlan.zhihu.com/p/573765504 10月13日晚9点,BIS就出口管制新规举行电话会议简报,出口执法助理副部长Thea Kendler主持会议.小白总结要点 ...
- [转帖]shell 实现行转列、列转行的几种方法
目录 shell 实现行转列.列转行的几种方法 awk 行转列 xargs 行转列 tr 列转行 参考资料 shell 实现行转列.列转行的几种方法 awk 行转列 以空格为分隔符 awk -F &q ...
- ARM平台安装Docker的方法
1. 找了一下有一个网站能够下载docker的arm的deb包可以使用 网址为: https://download.docker.com/linux/ubuntu/dists/xenial/pool/ ...
- vue/cli中css.sourceMap-open-inline-host-port-https-openPage-compress -devServer.proxy的简单介绍
Vue/cli4.0 配置属性--css.sourceMap 设置是否开启 css 的 sourse map功能. css 的 sourse map作用类似与 js 的 sourse map. 注意: ...
- 你不知道的<input type="file">的小秘密
限制file上传类型 很多时候,我们都需要使用 <input type="file"> 进行文件上传. 在上传的时候,我们需要对文件类型进行限制. 如果上传图片的时候. ...
- vs版本与version(内部版本号)的关系表table
为什么要查vs版本与内部verion的对应关系? 因为c++的项目需要对应的vs版本,给大型的c++项目升级vs版本是个耗时的工程,所以一般情况下开发者都会安装多个版本的vs. 对于sln文件,以文本 ...
- python2和python3的版本历史及入门书籍
python版本历史 我们端游项目使用是python2.7版本 32位 python2 2.7.18 last version on 2020.4.20 2.7 first version on 20 ...
- 深入浅出Java多线程(一):进程与线程
引言 大家好,我是你们的老伙计秀才. 在计算机系统的发展历程中,早期的计算机操作模式十分单一和低效.用户只能逐条输入指令,而计算机则按照接收指令的顺序逐一执行,一旦用户停止输入或进行思考,计算机会处于 ...