查看原文
其他

白话TCP拥塞控制:运粮的河道堵塞了怎么办?

The following article is from 码农翻身 Author 哈罗

专注于编程、互联网动态。最终将总结的技术、心得、经验(数据结构与算法、源码分析等)分享给大家,这里不只限于技术!还有职场心得、生活感悟、以及面经点击上方 "程序员小乐" ,选择“置顶公众号”,第一时间送达!


每日英文
Strive to make every day happy and meaningful, not for others, for yourself.
生活每天都是限量版,努力使每一天都开心而有意义,不为别人,为自己。


乐乐有话说
没人扶你的时候,自己要站直,路还长,背影要美。


来自公众号:码农翻身


图片来自网络

0 前言

张家村码头的粮食堆积如山,每天都需要用船运到镇里。


但是去镇上有50公里,只有水路可走。


一大早,码头工人们就开始干活了, 为了早点干完收工回家,一船接一船,拼命地发送粮食。


可是这水路不仅仅是张家村在运粮食,白头村还往外运石头, 东平村还往外运沙子,大家都拼命地往外发货物,再加上各式各样,络绎不绝的商船、客船, 大家很快就发现,船只太多,水面出现拥堵,工人们只好等待。


工人们想这也不是个事儿,大家围成一圈,蹲在码头上一边抽烟,一边商量对策。


水路很长,怎么判断水面是不是拥堵了呢?


新来的小张说道:“我有个办法,不要一下子发那么多船过去, 我们来个慢启动,首先运输一船粮食过去,船到镇上以后卸掉粮食马上返回,如果能在很短的时间内返回,说明水面交通状况还好,可以继续搬运粮食。


包工头老李说:“不错,这个船有检测水面拥堵状况的作用。然后呢?”


小张说: “接下来搬运2船粮食过去,如果依旧能够在预定的时间内返回,则继续搬运3船粮食,每次加一船, 依次类推。”


老王在码头上干了好几年, 他立刻跳了起来:“拉到吧你,这样太慢了!我提议,加快运输速度,每次发送的船只数量是上一次的两倍。”


也就是说,第一次发一条船,如果在预定时间内返回,第二次发2条船,然后是4条船,8条船!


老李说:“不行不行,每次都是之前的两倍,增长得太快了,大家如果都这么玩,水路很快就阻塞了。”


“我还没说完,” 老王补充, “为了防止拥塞,我们设置一个阈值(其实就是TCP中的ssthresh),当一次发船数量达到这个数,我们就降低速度,不要翻倍,每次只比上次多发一条船。”

老王一边说一边拿了一根木棍在地上画图:


(点击看大图)


我们把前面的阶段叫慢启动发船阶段,后面的阶段叫拥塞避免发船阶段。


大家对老王的方案纷纷叫好,就是它了!


只有小张慢悠悠地说:“随着每次发送船只的数量越来越多,水路早晚还是要阻塞的。”


“没事,”老王胸有成竹,“如果阻塞了,我们就回到最初的状态,从1条船,2条船,4条船......开始,但是,我们也要把阈值ssthresh调整一下,把它变小,嗯,假设上次阻塞时发船的数量是24, 那就把阈值调整为它的一半, 就是12。”


(点击看大图)


“不错,不错,当水路频繁阻塞时,这个阈值就会下降得很快,发到水面上的船也会大大减少。” 包工头老李总结,“我们要不按照这个方案试试?”


小张嘴里嘟囔着:“试试就试试,不过你得和白头村,东平村他们协调好,大家都得用这个方案才行,要不然我们就吃亏了。”


“那是自然!这事我来办!”老李满口答应。



故事结束了吗?其实没有,老王发明的其实叫做 TCP Tahoe算法。TCP的拥塞控制还有两个部分,即快速重传和快速恢复,这里再简单介绍一下。


快速重传比较简单,用一个图就可以表示:



在TCP中,数据都是有序号的,例如M1,M2,M3... 。


发送方发出了M1和M2, 接收方都收到了。


但是M3报文丢失了, 接收方没有收到,随后它收到了M4,M5,M6, 按照快速重传的算法,接收方重复确认M2,让发送方知道,M3没有收到。


当发送方收到3个对M2的重复确认的时候,它就意识到,坏菜了,M3丢了, 这时候不必继续等待M3设置的重传计时器到期,立刻重传M3。


统计表明,由于发送方尽早重传未被确认的报文段,可以使整个网络吞吐量提高约20%。


有了快速重传,可以改进下故事中的拥塞避免模型了。


(点击看大图)

当发送端收到三个重复确认的时候,就执行快速重传算法,并且把阈值减少。


但是这个时候它认为网络很可能没有发生阻塞, 不用执行慢启动算法,而是直接从新阈值开始,线性增大


这个算法称为TCP Reno版,被很多TCP的实现所采用。


如果您觉得不错,请别忘了转发、分享、点赞让更多的人去学习, 您的举手之劳,就是对小乐最好的支持,非常感谢!


如何您想进技术群交流,关注公众号在后台回复 “加群”,或者 “学习” 即可

著作权归作者所有


推荐阅读

阿里、腾讯、百度、华为、京东最新面试题汇集

程序员应该向产品经理学习什么?
内存泄漏与内存溢出总结
写下这行代码时,只有我和上帝知道是怎么回事


看完本文有收获?请转发分享给更多人
关注「程序员小乐」,提升技能

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存