TCP流量控制和拥塞控制

摘要:
第一个问题是收割台中的流量控制。TCP使用滑动窗口机制。第二个问题是报头中的拥塞控制。在具有不同网络速度的机器进行通信的环境中,拥有流量控制机制非常重要。

先来了解2个TCP的概念:

MSS:Maximum Segment Size,TCP一次传输发送的最大数据段长度。

RTT:Round-Trip Time,往返时延,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。

TCP传输大块数据时,肯定需要进行数据分段,而每个分段所能携带的最大数据就是1个MSS,假设大块数据为100个MSS,那么发送方发送的方式大概有如下两种:

1、  每次发送1个,收到接收方确认后,才发送下1个;

2、  一口气发送100个,然后收到对方一起确认;

显然,方式1中,一个RTT只能处理一个包,这样的传输效率太低了。而方式2看似很美好,实际会存在两个问题,一个是接收方的接收窗口未必能一次性接收这么多数据,另外一个是网络的带宽也不一定足够大,容易出现丢包事故。前一个问题就是标题中的流量控制(Flow control),TCP采用的是滑动窗口机制(Sliding window),后一个问题就是标题中的拥塞控制(Congestion control)。发送方的发送窗口或者说网络传输交互就取决于这两个问题的控制,谁控制的更严格,谁就占据了决定性因素,这也是为什么两者总是一起出现一起被讨论。

流量控制(Flow control):

TCP uses an end-to-end flow control protocol to avoid having the sender send data too fast for the TCP receiver to receive and process it reliably. Having a mechanism for flow control is essential in an environment where machines of diverse network speeds communicate.

TCP使用端到端流量控制协议来避免发送方发送数据太快,以致TCP接收方不能可靠地接收和处理数据。在不同网络速度的机器进行通信的环境中,具有流量控制机制至关重要。

TCP流量控制和拥塞控制第1张

                                    图一

图一为通过Wireshark抓包192.168.2.1和192.168.2.198的交互截图,可以看到有个标记Win,这个标记的含义就是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。

[TCP zerowindow]& [TCP window Full]

提到Win标记,就顺便谈一下Wireshark的[TCP zerowindow]和[TCP window Full],当Win=0时,Wireshark就会打上TCP zerowindow,表示缓存区已满,不能再接收数据了。当Wireshark在一个包上打上TCP window Full,就表示这个包的发送方已经把对方声明的接收窗口耗尽了。两者的共同特点都是传输暂停,前者的含义是发送方无法再接收数据,后者表示发送方无法再发送数据。

回过头来再来说滑动窗口。

TCP流量控制和拥塞控制第2张

              图二截取自《TCP/IP详解》

TCP流量控制和拥塞控制第3张

                图三取自参考资料

TCP流量控制和拥塞控制第4张

                 图四取自参考资料

图二和图三可以知道接收方会通知发送方当前已接收到的信息和可用窗口信息。

图三和图四可以看出来窗口滑动的过程。

总结:TCP的流量控制由滑动窗口来实现的,滑动窗口控制流量取决于接收方的窗口大小。

拥塞控制(Congestion control):

流量控制是端到端的交互,如果只是局域网内的两台设备交互,我想通过滑动窗口大概能控制得不差,但是实际网络的情况非常复杂,发送方和接收方之间还有路由器和交换机,网络传输线路又复杂,这个时候就需要拥塞控制。

拥塞控制主要有四个算法:慢启动、拥塞避免、快速重传和快速恢复。

慢启动:

讨论慢启动算法先来了解下拥塞窗口的概念,这是慢启动算法为TCP发送方新增的窗口,congestion window,简称cwnd。对应上文,发送方取拥塞窗口和滑动窗口的最小值作为发送上限,即谁严格谁起决定因素。

1、  连接建立开始,发送方不了解网络的情况,cwnd初始化比较小的值,RFC建议2-4个MSS,具体视MSS的大小而定;

If (MSS <= 1095 bytes)

      then win <= 4 * MSS;

If (1095 bytes < MSS < 2190 bytes)

      then win <= 4380;

If (2190 bytes <= MSS)

      then win <= 2 * MSS; 摘自rfc3390.

2、  如果发送出去的包都被ACK,说明还未到达拥塞点,则增加拥塞窗口,RFC建议的是每收到n个ACK,则cwnd新增n个MSS,呈指数关系增长,虽然这个过程看似比较快,但是基数比较低,所以被称为“慢启动”。

拥塞避免:

其实慢启动除了维护了cwnd,还维护了慢启动临界值ssthresh,一般将ssthresh设置为65535字节。在cwnd<=ssthresh时,还是处于慢启动环节,一旦>ssthresh,开始进入拥塞避免。

RFC建议拥塞避免环节,无论一个RTT可以收到多少个ACK,每一次确认都只新增1个MSS,呈线性关系增长,避免快速的触碰到网络拥塞点。

TCP流量控制和拥塞控制第5张

              图五取自参考资料

快速重传和快速恢复:

进入拥塞避免之后,最终还是会碰到拥塞点,发送方此时迟迟得不到确认,当然得不到确认也有可能是因为延迟确认导致的。发送方此时决定等待一段时间,如果一段时间后还是得不到确认,就发起重传,这个过程叫做超时重传。从发出原始包到重传该包的时间叫做RTO(Retransmission TimeOut)。

进入超时重传后,RFC建议将cwnd设置为1个MSS,而对于ssthresh,RFC5681建议的是发生拥塞时未被ACK的数据量的1/2,但必须大于等于2个MSS。然后重新进入慢启动环节。超时重传因为需要等待RTO之后才能进入新的恢复环节,所以对网络性能的影响是比较大的。所以各路大神又想到了一个新的方式,看能否无需等待RTO,就发起重传,这种方式叫做快速重传。快速重传规定在收到3个及以上重复ACK时就触发重传,不再进入慢启动环节,然后直接进入拥塞避免,这个就是快速恢复算法。为什么是3个?因为1-2个重复ACK,很有可能是乱序,只有在3个及以上的时候才是有可能丢包了。关于具体快速重传和快速恢复的算法可以看下参考资料,已经写得非常详细了。

以上就是我对TCP流量控制和拥塞控制的理解,如有不当言论,欢迎留言交流反馈。

参考资料:

https://en.wikipedia.org/wiki/Transmission_Control_Protocol

https://en.wikipedia.org/wiki/TCP_congestion_control

https://www.zhihu.com/question/32255109

https://www.zhihu.com/question/38749788

https://coolshell.cn/articles/11564.html

https://coolshell.cn/articles/11609.html

http://blough.ece.gatech.edu/4110/TCPTimers.pdf

http://www.eventhelix.com/RealtimeMantra/Networking/TCP_Slow_Start.pdf

免责声明:文章转载自《TCP流量控制和拥塞控制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇组合图制作,Graphpad Prismsql server 2012提示评估期已过的解决办法 附序列号下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况

公司的同事们在分析网页加载慢的问题,忽然使用到了Wireshark工具,我就像发现新大陆一样好奇,赶紧看了看,顺便复习了一下相关协议。上学时学的忘的差不多了,汗颜啊! 报文封装整体结构 mac帧头定义 /*数据帧定义,头14个字节,尾4个字节*/ typedef struct _MAC_FRAME_HEADER { char m_cDstMacAddr...

《图解 HTTP》 摘要一

学习过程对书本的内容的摘要以及总结,逐步完善,带有个人理解成分。 Web 及网络基础 使用 HTTP 协议访问 Web 客户端:通过获取请求获取服务资源的 Web 浏览器等 HTTP 全称:HtyperText Transfer Protocol WWW 全称:Wrold Wide Web SGML 标准通用标记语言 全称:Standard Gener...

工具-windows命令--查看端口占用情况,关闭端口

假如我们需要确定谁占用了我们的9050端口 1、Windows平台 在windows命令行窗口下执行: 1.查看所有的端口占用情况 C:>netstat -ano   协议    本地地址                     外部地址               状态                   PID   TCP    127.0.0....

构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境

构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境 整个环境的结构图。 一、准备工作 gitlab和harbor我是安装在kubernetes集群外的一台主机上的。 1.1、设置镜像源 docker-ce.repo [root@support harbor]# cat /etc/yum.repos.d/d...

IOS网络编程之Socket详解

Socket描述了一个IP、端口对。它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息。所以,Socket一定包含了通信的双发,即客户端(Client)与服务端(server)。1)服务端利用Socket监听端口;2)客户端发起连接;3)服务端返回信息,建立连接,开始通信;4)客户端,服务端断开连接。 1...

Linux内核 TCP/IP、Socket参数调优

/proc/sys/net目录所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这些重要的参数: 参数(路径+文件) 描述 默认值 优化值 /proc/sys/net/core/rmem_default 默认的TCP数据接收窗口大小(...