这里只是简单梳理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

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

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

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

    周五晚上.终于下了雨.所以也终于能够乱七八糟多写点松散的东西了... 方法论问题. 这个题目太大以至于内容和题目的关联看起来有失偏颇.只是也无所谓,既然被人以为"没有方法论"而歧视 ...

  2. TCP拥塞控制算法

    转自浅谈TCP拥塞控制算法 本篇文章介绍了几种经典的TCP拥塞控制算法,包括算法原理及各自适用场景. 回顾上篇文章:浅谈 redis 延迟 前言 TCP 通过维护一个拥塞窗口来进行拥塞控制,拥塞控制的 ...

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

    [摘要]对多种TCP拥塞控制算法进行简要说明,指出它们的优缺点.以及它们的适用环境. [关键字]TCP拥塞控制算法 优点    缺点   适用环境公平性 公平性 公平性是在发生拥塞时各源端(或同一源端 ...

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

    正文 非常多人会觉得一个好的TCP拥塞控制算法会让连接加速,这样的观点是错误的.恰恰相反,全部的拥塞控制算法都是为了TCP能够在贪婪的时候悬崖勒马,大多数时候.拥塞控制是减少了数据发送的速度. 我在本 ...

  5. 浅谈TCP拥塞控制算法

    TCP通过维护一个拥塞窗口来进行拥塞控制,拥塞控制的原则是,只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入 ...

  6. 【转载】TCP拥塞控制算法 优缺点 适用环境 性能分析

    [摘要]对多种TCP拥塞控制算法进行简要说明,指出它们的优缺点.以及它们的适用环境. [关键字]TCP拥塞控制算法 优点    缺点   适用环境公平性 公平性 公平性是在发生拥塞时各源端(或同一源端 ...

  7. 网络拥塞控制(三) TCP拥塞控制算法

    为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由V. Jacobson在1988年的论文中提出的TCP的拥塞控制由“慢启动(Slow start)”和“拥塞避免(Congestion  ...

  8. TCP拥塞控制算法之NewReno和SACK

    TCP拥塞控制算法之NewReno和SACK 2018年05月23日 19:10:03 吃吃爱学习 阅读数:1446    版权声明:程序媛吃吃的博客 https://blog.csdn.net/m0 ...

  9. TCP拥塞控制算法内核实现剖析(十)

    内核版本:3.2.12 主要源文件:linux-3.2.12/ net/ ipv4/ tcp_veno.c 主要内容:Veno的原理和实现 Author:zhangskd @ csdn blog 概要 ...

随机推荐

  1. MarkDown格式作业模板

    发布的随笔可复制下面的MarkDowm模板 注意事项 标题第XX次作业替换成相应的第一次作业.第二次作业...... 代码托管的链接一定要换成自己的项目 码云提交历史截图必须是自己每周的提交截图 #& ...

  2. Coding(码市)教程(一):基础配置

    作者:Adaaaagio 出处:http://www.cnblogs.com/zyx418 欢迎转载,希望能够帮到更多的人,转载也请保留这段申明,谢谢! 初识coding是在新入职的公司,前辈说我们用 ...

  3. cratedb json 数据导入

    基本环境的搭建,可以参考相关文档,或者直接使用docker 安装 docker run -d -p 4200:4200 crate 导出mongodb数据(可选,同时使用工具进行数据类型转换) mon ...

  4. Windows 2008 关闭远程桌面的单用户多会话模式

    Windows 2008 关闭远程桌面的单用户多会话模式 在腾讯云上购买了一台云服务器. 因为设置了自动登录,在远程桌面连接后会启动一个新的会话,然后软件被运行了两次,端口被占用,无法起动. 还有可能 ...

  5. linux shell 模拟post请求

    Linux 下curl模拟Http 的get or post请求.   一.get请求 curl "http://www.baidu.com"  如果这里的URL指向的是一个文件或 ...

  6. 大型发布会现场的 Wi-Fi 应该如何搭建(密集人群部署wifi抗干扰)?

    原文连接: http://www.zhihu.com/question/20890194 WiFi网络的部署要远远比一般人想象的复杂,不是说放上几十个AP带宽就自动增加几十倍,恰恰相反,简单放几十个A ...

  7. oracle/ms sql 系统表

    sql server系统表详细说明 sysaltfiles 主数据库 保存数据库的文件 syscharsets 主数据库字符集与排序顺序 sysconfigures主数据库 配置选项 syscurco ...

  8. 写给C#程序员的javascript说明: 各类型变量和prototype

    在javascript中存在类似的私有变量 公有变量和静态变量 私有: var AA=function(){ var aa="im private"; }; 私有变量通过闭包访问. ...

  9. vim配置之安装脚本

    vimConfig/install/install.sh git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle cp ...

  10. 1027代码审计平台 1-sonar scanner

    1.代码审计 1.1综合性的代码分析平台 sonar支持自定义规则,较多的公司使用 360火线 1.2IDE辅助功能 Xcode.Android studio 阿里巴巴Java开发手机ide插件支持 ...