Linux TCP拥塞控制算法原理解析

这里只是简单梳理TCP各版本的控制原理,对于基本的变量定义,可以参考以下链接:

TCP基本拥塞控制http://blog.csdn.net/sicofield/article/details/9708383

TCP中RTO计算http://www.tuicool.com/articles/Yn6vEr

TCP拥塞控制名词解释:

1.awnd(advised window) 通告窗口,由接收端tcp发送给发送端tcp,告诉发送端自己能用于接收新的数据包的当前可用空间。

2.cwnd(congestion window)拥塞窗口,人为引入的变量,用于拥塞控制。因为如果单独使用awnd,每次都按接收端最大窗口发送易引发网络的瞬时拥塞瞬时进入拥塞避免剧烈降低网络利用率。

3.ssthresh(slow start thresh)慢启动阈值,用于确定使用慢启动算法还是拥塞避免算法。当前窗口小于ssthresh的时候,使用慢启动算法按指数增加窗口;当前窗口等于ssthresh时,使用慢启动或拥塞避免算法增长发送窗口都可以;当前发送窗口大于ssthresh时,使用拥塞避免算法,按线性增加发送窗口。

4.发送窗口W = min(cwnd, awnd)

5.duplicate ACK重复ACK,TCP接收端在接受到错序/失序数据包时应该立即向发送端返回重复ACK。如接收端已经顺序收到1000号前的包,返回发送端1001,然后接收端接着收到了1002号包,而不是期望的1001号包,则其立即返回给发送端1001的ACK包,这个ACK相对于第一次的1001ACK就是重复ACK包。

原始版TCP协议--TCP-Tahoe:

1.慢启动

初始值cwnd=1(linux3.0之后是10),ssthresh初始值可以被设置为任意大(可以设置为awnd或更大,这样总是使TCP从慢启动算法开始,而不是拥塞避免算法),如linux 3.2.12是int最大值0x7fffffff.

该阶段,每个rtt周期发送窗口W加倍。时间曲线图中表现为指数曲线。

2.拥塞避免

如果出现丢包,由于TCP无法确认丢包类型,所以就认为发生了网络拥塞,重传包并进入拥塞避免算法。操作是:

ssthresh = max(flight size/2, 2*SMSS),flight size为当前发送窗口中已经发送但还没有收到ACK的包个数,即flight size<=W,SMSS为发送端最大分组大小。

cwnd=1(或其他初始值,如10),然后就可以重新从慢启动算法增加发送窗口。

3.丢包,重现慢启动

在上一步的基础上,根据新的初值,回到第1步重新执行慢启动。

如下图:

说明:

1.tcp启动时,cwnd=1,ssthresh=16,时间轴0-4是慢启动算法阶段。然后发送窗口增加到ssthresh时,进入拥塞避免阶段,时间轴4-12.

2.发送丢包时,cwnd重新置为1,ssthresh设置为当前拥塞窗口(24)的一半,即12.时间轴上12-13.

3.上一步设置完新的cwnd和ssthresh后,重新进入第1步进行执行慢启动算法。

后期Tahoe版本也引入了快重传算法(原始检测到丢包需要等到rto超时才能重传,快重传就是连续收到3个ack就立即重传)。

快恢复版本TCP--TCP-Reno(增加快重传/快恢复算法):

Tahoe版本检测丢包只能通过RTO超时依然收不到ACK时才能开始重传,Reno版的修改是,引入快重传机制:当收到对方连续3次重复ACK时,不必再等待RTO超时,认为网络已经发生拥塞丢包,立即重传数据包。同时,因为RTO时间内连续收到3次ACK,认定网络状况依然良好,丢包可能是网络发生了瞬时拥塞。所以不必对发送窗口进行过度调整。

快重传机制(Fast Retransmit):

当收到3次连续的重复ACK时,立即重传数据包,不必等待RTO超时。

注意:快重传不必一定跟快恢复算法同时使用。Tahhoe版本中也可以使用快重传,但cwnd依然调整为1,而不是快恢复算法的cwnd/2.

窗口示例:

快重传/快恢复算法(Fast Recovery):

1.收到3次重复ACK,设置ssthresh=cwnd/2。

2.重传丢失的包,设置cwnd=ssthresh+3。3是根据网络“数据包守恒”定律,即根据ACK机制,收到3个重复ACK,说明有3个数据包已经离开了网络,所以cwnd+3。

3.每收到一个额外的重复ACK(包5),cwnd=cwnd+1。只是为了反应出一个包已经离开网络的事实。

4.传输包

5.如果收到新数据包的ACK(包7或包9),cwnd=ssthresh,称为“缩小窗口”,退出快恢复阶段,进入拥塞避免阶段。

对应下图时间轴12-13.

总结:

TCP拥塞控制算法 RFC文档链接http://www.faqs.org/rfcs/rfc2581.html

新版本TCP--TCP NewReno(相对Reno少量但却重要的修改是对partial acknowledgment部分确认的处理):

Reno版本不足:

当发送窗口只有一个包丢失,则快重传后,一个rtt后收到的第一个ack会确认快重传启动之前全部已经发送的数据包。但是如果发送窗口中多个包丢失,那么快重传后第一个收到的ack只能确认发送窗口中的部分数据,称为“部分确认”。NewReno处理“部分确认”的方法是,认为那个包丢失并重传那个包。

NewReno新的快重传/快恢复算法:

1.当收到3次重复ACK,并且发送者并不处于快恢复过程时

设置ssthresh = cwnd/2

记录recover=max sequence number,快重传算法之前已传输的最大的数据包序列号(包10或更大)。

2.重传丢失包(包5),设置cwnd=ssthresh+3

3.如果继续收到重复ACK(包5),cwnd=cwnd+1

4.发送包(由于上一步cwnd窗口扩张)

5.当收到新的数据包的ACK(包7或包9),这个ACK可能是对第2步重传或稍后的重传的确认。

if (ACK确认所有的从丢失包一直到并包括“recover”的数据包)

  设置cwnd=ssthresh或min (ssthresh, FlightSize + MSS),然后退出快恢复阶段。

else

  重传下一个没有被确认的数据包;将cwnd=cwnd-新确认的数据包个数+1,发送新的包。这样缩小窗口的目的是,当快恢复算法最终退出时,大约有ssthresh数量的数据包存在于网络中。如果收到新的ack,重复执行第3-4步。

总结:

TCP NewReno RFC文档链接http://www.faqs.org/rfcs/rfc2582.html

有理解错误的地方,欢迎指出。

时间: 2024-10-19 14:47:45

Linux TCP拥塞控制算法原理解析的相关文章

TCP拥塞控制算法纵横谈-BBR vs Reno/CUBIC

不管是在工作中,还是平时与技术上的朋友一起讨论关于BBR的问题,都不可避免的会面对"BBR和CUBIC之间的对比"的问题,毕竟CUBIC在Linux平台是默认的拥塞算法,已经好多年了.        现在突然有了个被宣传的神乎其神的BBR算法,如果真的有那么好,那肯定要比CUBIC好,如果真的这样,到底好在哪里呢?如果不是这样,那么问题又是什么呢?我想关于BBR好在哪里这个问题是不必回答的,因为如果在效率和公平性上秒杀了CUBIC,那基本上的结果就是换掉BBR,除了理论工作者没有人会问

TCP拥塞控制算法-从BIC到CUBIC

本文旨在帮助大家理解TCP CUBIC拥塞控制算法背后的点点滴滴以及其方程式为什么就是那样子的.一直以来,很多人都觉得CUBIC算法非常复杂,涉及到复杂的天书般的"3次曲线"...然而,CUBIC并不像大家以为的那样复杂,之所以觉得复杂是因为没有理解其历史和背景. 本文就是介绍CUBIC的历史和背景的... BIC算法 BIC算法对窗口可能的最大值进行二分查找,它基于以下的事实:1.如果发生丢包的时候,窗口的大小是W1,那么要保持线路满载却不丢包,实际的窗口最大值应该在W1以下:2.如

TCP拥塞控制算法纵横谈-Illinois和YeAH

周五晚上.终于下了雨.所以也终于能够乱七八糟多写点松散的东西了... 方法论问题. 这个题目太大以至于内容和题目的关联看起来有失偏颇.只是也无所谓,既然被人以为"没有方法论"而歧视了.这里也就抛出一些伪方法论,总之,就是一些大而空的东西.我并非说方法论没实用,而是说方法论太实用了,以至于绝不能误解它.难道方法论不是从已经成功的经验中总结出来的吗?假设还没有成功的案例,那么方法论从何而生呢?So,我仅仅能从现成的东西入手了...分类学是一个贯通古今的学科.也蕴含在实在太多的方法论中,从中

Google&#39;s BBR拥塞控制算法模型解析

在进入这篇文章的正文之前,我还是先交代一下背景.1.首先,我对这次海马台风对深圳的影响非常准确,看过我朋友圈的都知道,没看过的也没必要知道,白赚了一天"在家办公"是收益,但在家办公着实效率不高,效果不好.2.我为什么可以在周五的早上连发3篇博客,一方面为了弥补因为台风造成"在家办公"导致的时间蹉跎,另一方面,我觉的以最快的速度分享最新的东西,是一种精神,符合虔诚基督徒的信仰而不是道德约束.3.上半年的时候,温州皮鞋厂老板推荐了一个会议,大致是说"迄今为止的

TCP拥塞控制算法

转自浅谈TCP拥塞控制算法 本篇文章介绍了几种经典的TCP拥塞控制算法,包括算法原理及各自适用场景. 回顾上篇文章:浅谈 redis 延迟 前言 TCP 通过维护一个拥塞窗口来进行拥塞控制,拥塞控制的原则是,只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入到网络中的数据包数. TCP 拥塞控制算法发展的过程中出现了如下几种不同的思路: 基于丢包的拥塞控制:将丢包视为出现拥塞,采取缓慢探测的方式,逐渐增大拥

让人很容易误解的TCP拥塞控制算法

正文 很多人会认为一个好的TCP拥塞控制算法会让连接加速,这种观点是错误的,恰恰相反,所有的拥塞控制算法都是为了TCP可以在贪婪的时候悬崖勒马,大多数时候,拥塞控制是降低了数据发送的速度. 我在本文中会针对近期跟业内朋友之间的聊天记录,总结出三言两语.        TCP拥塞控制的终极目标绝对不是加快数据发送的速度,这种理解非常自私且肤浅!它的终结目标是在公平占有带宽的前提下无限度提高带宽的利用率!        如果你只关注一个独立的TCP连接本身,那么你也许永远都不可能设计出什么比较好的算

让人非常easy误解的TCP拥塞控制算法

正文 非常多人会觉得一个好的TCP拥塞控制算法会让连接加速,这样的观点是错误的.恰恰相反,全部的拥塞控制算法都是为了TCP能够在贪婪的时候悬崖勒马,大多数时候.拥塞控制是减少了数据发送的速度. 我在本文中会针对近期跟业内朋友之间的聊天记录.总结出三言两语.        TCP拥塞控制的终极目标绝对不是加快数据发送的速度,这样的理解非常自私且肤浅!它的终结目标是在公平占有带宽的前提下无限度提高带宽的利用率! 假设你仅仅关注一个独立的TCP连接本身,那么你或许永远都不可能设计出什么比較好的算法,但

TCP拥塞控制算法 优缺点 适用环境 性能分析

[摘要]对多种TCP拥塞控制算法进行简要说明,指出它们的优缺点.以及它们的适用环境. [关键字]TCP拥塞控制算法 优点    缺点   适用环境公平性 公平性 公平性是在发生拥塞时各源端(或同一源端建立的不同TCP连接或UDP数据报)能公平地共享同一网络资源(如带宽.缓存等).处于相同级别的源端应该得到相同数量的网络资源.产生公平性的根本原因在于拥塞发生必然导致数据包丢失,而数据包丢失会导致各数据流之间为争抢有限的网络资源发生竞争,争抢能力弱的数据流将受到更多损害.因此,没有拥塞,也就没有公平

在Wireshark的tcptrace图中看清TCP拥塞控制算法的细节(CUBIC/BBR算法为例)

这是一个令人愉快的周末,老婆上周从上海回来,这周末小小幼儿园组织去坪山秋游,比较远,因此大家都必须早早起来,而我更加有理由起床更早一些来完成这篇短文,因为要出去一整天,如果早上起不来,一天都没什么时间了.        另外,最近有人问我,为什么我总是喜欢在技术文章后面加一些与技术毫不相关的话,我说,咱们小时候学古文的时候,那些古代的作者不也是喜欢在文章最后写一段毫不相关的"呜呼...""嗟夫..."之类的吗?人写文章总是有感而发,所以,点题总是必要的.也有同事问,