TCP要点有四,一曰有连接,二曰可靠传输,三曰数据按照到达,四曰端到端流量控制 。注意,TCP被设计时只保证这四点,此时它虽然也有些问题,然而很简单,然而更大的问题很快呈现出来,使之不得不考虑和IP网络相关的东西,比如公平性,效率,因此增加了拥塞控制,这样TCP就成了现在这个样子 。
为什么要进行拥塞控制
要回答这个问题,首先必须知道什么时候TCP会出现拥塞 。TCP作为一个端到端的传输层协议,它并不关心连接双方在物理链路上会经过多少路由器交换机以及报文传输的路径和下一条,这是IP层该考虑的事 。然而,在现实网络应用中,TCP连接的两端可能相隔千山万水,报文也需要由多个路由器交换机进行转发 。交换设备的性能不是无限的!, 当多个入接口的报文都要从相同的出接口转发时,如果出接口转发速率达到极限,报文就会开始在交换设备的入接口缓存队列堆积 。但这个队列长度也是有限的,当队列塞满后,后续输入的报文就只能被丢弃掉了 。对于TCP的发送端来说,看到的就是发送超时丢包了 。

文章插图
如何进行拥塞控制
拥塞窗口 cwnd
首先需要明确的是,TCP是在发送端进行拥塞控制的 。TCP为每条连接准备了一个记录拥塞窗口大小的变量cwnd1,它限制了本端TCP可以发送到网络中的最大报文数量2 。显然,这个值越大,连接的吞吐量越高,但也更容易导致网络拥塞 。所以,TCP的拥塞控制本质上就是根据丢包情况调整cwnd,使得传输的吞吐率尽可能地大!而不同的拥塞控制算法就是调整cwnd的方式不同!
注1: 本文中的cwnd以发送端的最大报文段长度SMSS为单位的 注2: 这个数量也受对端通告的窗口大小限制
linux 用户可以使用 ss --tcp --info 查看链接的cwnd值
拥塞控制算法
TCP从诞生至今,已经有了多种的拥塞控制算法,直到现在还有新的在被提出!其中TCP Tahoe(1988)和TCP Reno(1990)是最初的两个算法 。虽然看上去年代很就远了,但 Reno算法直到现在还在广泛地使用 。
- Tahoe 提出了1)慢启动,2)拥塞避免,3)快速重传
- Reno 在Tahoe的基础上增加了4)快速恢复
Tahoe算法的基本思想是
- 首选设置一个符合情理的初始窗口值
- 当没有出现丢包时,慢慢地增加窗口大小,逐渐逼近吞吐量的上界
- 当出现丢包时,快速地减小窗口大小,等待阻塞消除
相关视频推荐
LinuxC++零拷贝的实现 用户态协议栈 ntytcp
90分钟搞定tcp/ip协议栈
LinuxC++后台服务器开发架构师免费学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
【文章福利】:小编整理了一些个人觉得比较好的学习书籍、视频资料共享在qun文件里面,有需要的可以自行添加哦!(需要视频资料后台私信“1”自取)

文章插图
Tahoe 拥塞避免 (congestion-avoidance)
当我们在理解拥塞控制算法时,可以假想发送端是一下子将整个拥塞窗口大小的报文发送出去,然后等待回应 。
Tahoe采用的是加性增乘性减(Additive Increase, Multiplicative Decrease, AIMD)方式来完成缓慢增加和快速减小拥塞窗口:
发送端发送整窗的数据:
- 如果没有丢包,则 cwnd = cwnd + 1
- 如果出现丢包了,则 cwnd = cwnd / 2
为什么丢包后是除以2呢, 这里的2实际上是一个折中值!用下面的例子来解释!

文章插图
?
物理传输路径都会有延时,这个延时也让传输链路有了传输容量(transit capacity)这样一个概念,同时我们把交换设备的队列缓存称为队列容量(queue capacity).比如下面这样一个连接,传输容量是M,队列容量是N.
当cwnd小于M时,不会使用R的队列,此时不会有拥塞发生;当cwnd继续增大时,开始使用R的队列,此时实际上已经有阻塞了!但是A感知不到,因为没有丢包! 当cwnd继续增大到M + N时,如果再增大cwnd,就会出现丢包 。此时拥塞控制算法需要减小cwnd,那么减小到多少合适呢? 当然是减少到不使用R的缓存,或者说使得cwnd = M,这样可以快速解除阻塞 。
推荐阅读
- 图文并茂,讲解TCP和UDP协议的原理以及区别
- KET每日一词丨Sheet sheet是什么意思
- 技嘉主板BIOS设置图解教程 技嘉主板bios设置
- 杨桃的正确吃法图解 杨桃怎么吃
- 小说三要素关系图解 小说三要素
- 人参果的正确吃法图解 人参果的功效与作用
- 实用倒桩技巧“几进几退” 倒桩技巧图解
- 手把手教你在netty中使用TCP协议请求DNS服务器
- 扭力扳手使用方法图解与注意事项 扭力扳手怎么用
- 这份小区健身器材使用攻略请收好 小区健身器材使用图解
