TCP慢启动,拥塞控制,ECN 笔记

1,TCP慢启动

TCP在连接过程的三次握手完成后,开始传数据,并不是一开始向网络通道中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞;而是根据初始的cwnd大小逐步增加发送的数据量,cwnd初始化为1个最大报文段(MSS)大小(这个值可配置不一定是1个MSS);每当有一个报文段被确认,cwnd大小指数增长。 
开始 —> cwnd = 1 
1个RTT后 —> cwnd = 2*1 = 2 
2个RTT后 —> cwnd = 2*2= 4 
3个RTT后 —> cwnd = 4*2 = 8

2,拥塞避免

cwnd不能一直这样无限增长下去,一定需要某个限制。TCP使用了一个叫慢启动门限(ssthresh)的变量,一旦cwnd>=ssthresh(大多数TCP的实现,通常大小都是65536),慢启动过程结束,拥塞避免阶段开始; 
拥塞避免:cwnd的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确认时,cwnd的大小加1,cwnd的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。 
非ECN环境下的拥塞判断,发送方RTO超时,重传了一个报文段;

  • 1,把ssthresh降低为cwnd值的一半;
  • 2,把cwnd重新设置为1;
  • 3,重新进入慢启动过程。

3,快速重传

快速重传,TCP在收到重复的3次ACK时,会认为重传队列中的第一个报文段被网络丢弃,但由于收到的重复的3次ACK,则认为该报文段之后的三个报文已经被接收端收到,则不等待重传定时器超时,直接重发重传队列中的第一个报文段。

  • 1,把ssthresh设置为cwnd的一半
  • 2,把cwnd再设置为ssthresh的值(具体实现有些为ssthresh+3)
  • 3,重新进入拥塞避免阶段。

4,快速恢复

快速恢复的数据包守恒原则,即同一个时刻在网络中的数据包数量恒定,“老”数据包离开后,才能向网络中发送“新”的数据包。如果发送方收到一个重复的ACK,TCP的ACK机制就表明有一个数据包离开,此时cwnd加1。

  • 1,当收到3个重复ACK时,把ssthresh设置为cwnd的一半,把cwnd设置为ssthresh的值加3,然后重传丢失的报文段,加3的原因是因为收到3个重复的ACK,表明有3个“老”的数据包离开了网络。
  • 2,再收到重复的ACK时,拥塞窗口增加1。
  • 3,当收到新的数据包的ACK时,把cwnd设置为第一步中的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。

5,ECN(Explicit Congestion Notification),WWDC 2017 再次提到

5.1,现有TCP在拥塞时出现的问题

非ECN环境下,在网络中间路由器丢包时,TCP协议通过RTO超时来重传丢失的包,保证数据可靠性。 
对于网络链路中的路由器来说,当中间路由器队列过载导致丢包后,各主机之间的TCP连接并不感知中间路由器的转发队列的忙闲状态。而是在RTO定时器超时之后,由于没有收到ACK,开始重传报文。而这个定时器的时间相对较长,通常从几秒到几十秒不等。报文丢弃导致多路TCP开始降低发送速率,甚至在一个窗口发送完毕之后,TCP的重传定时器没有超时之前,整个发送过程会偶尔停滞。在所有TCP降低性能之后,路由器的转发队列拥塞得到缓解,不再丢弃报文,所有TCP又会同时提高发送速率,到达一定程度之后,路由器又开始丢弃报文,并重复刚才TCP的重传过程。该现象的问题有:

  • 1、丢包导致TCP重传,该重传定时器的时间较长,对时延敏感的应用来说,影响用户感受。
  • 2、丢包之后,所有TCP开始进行退避,下调发送性能,拥塞得到缓解,但此时的网络利用率无法达到最优。
  • 3、在拥塞缓解之后,TCP为了获得发送的最优性能,又继续扩大发送窗口,直到发现丢包,重复上述问题过程。

5.2,中间路由器拥塞控制队列

路由器的转发队列通常实现了RED功能,即路由器会根据当前队列的平均长度来做丢包决策,并随机丢弃一些TCP报文段,而不是等到队列满载,很好地避免了所有TCP同时超时的问题。

5.3,ECN设计

通过在TCP和IP首部的修改,能解决以下问题:

  • 1,所有的TCP发送端尽快感知中间路径的拥塞,主动减小cwnd;
  • 2,对于在中间路由器中超过平均队列长度的TCP报文进行ECN标记,并继续进行转发,不丢弃报文,避免了报文丢弃和发送端重传;
  • 3,由于显式的标识拥塞的发生,不用再等待RTO超时(时间比较长)再重发数据,提升了时延敏感应用的直观感受。
  • 4,与非ECN网络环境相比,网络利用率更高,不再是在过载和轻载之间来回震荡。

5.4,对IP和TCP首部的修改

IP首部的修改

     0     1     2     3     4     5     6     7  +-----+-----+-----+-----+-----+-----+-----+-----+  |          DS FIELD, DSCP           | ECN FIELD |  +-----+-----+-----+-----+-----+-----+-----+-----+    DSCP: differentiated services codepoint    ECN:  Explicit Congestion Notification  The Differentiated Services and ECN Fields in IP.  +-----+-----+  | ECN FIELD |  +-----+-----+    ECT   CE         [Obsolete] RFC 2481 names for the ECN bits.     0     0         Not-ECT     0     1         ECT(1)     1     0         ECT(0)     1     1         CE  The ECN Field in IP.

IP首部的TOS字段中的第7和8bit的res字段被重新定义为ECN字段,其中有四个取值,在RFC3168中描述,00代表该报文并不支持ECN,所以路由器的将该报文按照原始非ECN报文处理即可,即,过载丢包。01和10这两个值针对路由器来说是一样的,都表明该报文支持ECN功能,如果发生拥塞,则ECN字段的这两个将修改为11来表示报文经过了拥塞,并继续被路由器转发。针对01和10的具体区别请参考RFC3168。 
所以路由器转发侧要支持ECN,需要有以下新增功能:

  • 1、 当拥塞发生时,针对ECN=00的报文,走原有普通非ECN流程,即,进行RED丢包。
  • 2、 当拥塞发生时,针对ECN=01或ECN=10的报文,都需要修改为ECN=11,并继续转发流程。
  • 3、 当拥塞发生时,针对ECN=11的报文,需要继续转发。
  • 4、 为了保证与不支持ECN报文的公平性,在队列超过一定长度时,需要考虑对支持ECN报文的丢弃。

TCP首部的修改

    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  |               |               | C | E | U | A | P | R | S | F |  | Header Length |    Reserved   | W | C | R | C | S | S | Y | I |  |               |               | R | E | G | K | H | T | N | N |  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  CWR: Congestion Window Reduce  ECE: ECN-Echo  The new definition of bytes 13 and 14 of the TCP Header.

针对主机侧的修改,首部将bit8和bit9的res字段修改为CWR和ECE。在RFC3168中的设计如下:

  • 1、 在TCP接收端收到IP头中的ECN=11标记,并在回复ACK时将ECE bit置1。并在后续的ACK总均将ECE bit置1。
  • 2、 在TCP发送端收到ECE bit置1的ACK报文时,需要将自己的发送速率减半,并在发送下一个报文时,将CWR bit置1。
  • 3、 在接收端收到CWR bit置1的报文时,后续的ECE bit将不再置1。直到再次收到IP首部ECN=11时,重复上述过程。
  • 4、 TCP发送端在收到一个ECE=1时,缩小发送窗口,并且在本次RTT时间内将不再再次缩小发送窗口。
  • 5、 TCP接收端向发送端回应ACK时,如果该ACK是一个不带数据的“纯”ACK,那么必须IP首部ECN=00,因为TCP没有机制对纯ACK进行响应,就无法针对纯ACK发送拥塞通知。
  • 6、 对于支持IP ECN的主机,TCP层在发送报文时需要将IP首部中的ECN置为01或10

原文链接:

http://www.cnblogs.com/edisongz/p/6986527.html

时间: 2024-10-29 10:46:20

TCP慢启动,拥塞控制,ECN 笔记的相关文章

【转】TCP/IP详解学习笔记(二)

TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节 1.静态IP选路 1.1.一个简单的路由表 选路是IP层最重要的一个功能之一.前面的部分已经简单的讲过路由器是通过何种规则来根据IP数据包的IP地址来选择路由.这里就不重复了.首先来看看一个简单的系统路由表. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface192.168.11.0    *               255.

TCP自时钟/拥塞控制/带宽利用之脉络半景解析

0.说明 搬家公司的人很多都穿皮鞋!Why? 这个题目不是很明确,而且这个文章比较长,也算是我的一个阶段性总结,既然是总结,就不必为题目而纠结了.在端午假期的最后来做这个总结也实属不易(假期前两天加班,没有完成预期的计划,低落),记得很早以前写那篇<TCP协议疑难杂症全景解析>的时候跟现在一个心情.翻翻以前的记录,写那个的时候是2011年的7月初,小小才刚刚半个月,如今小小已经马上5岁了,时间过得真快啊,弹指一挥间!!回首过去的五年间,最累的时候是在2011年中到2014年初这两年半的时间,有

TCP/IP详解学习笔记 这位仁兄写得太好了.(转载)

TCP/IP详解学习笔记   这位仁兄写得太好了 TCP/IP详解学习笔记   这位仁兄写得太好了. http://blog.csdn.net/goodboy1881/category/204448.aspx TCP/IP详解学习笔记(13)-TCP坚持定时器,TCP保活定时器 TCP/IP详解学习笔记(12)-TCP的超时与重传TCP/IP详解学习笔记(11)-TCP交互数据流,成块数据流 TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着

TCP流量控制与拥塞控制

 一.TCP建立连接后,通信双方都同时可以进行数据的传输:在保证可靠性上,采用超时重传和捎带确认机制:在流量控制上,采用滑动窗口协议,协议中规定,窗口内未经确认的分组需要进行重传:在拥塞控制上,采用慢启动算法. (一)拥塞控制: 1. TCP慢启动.拥塞避免.快速重传.快速回复 为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由V. Jacobson在1988年的论文中提出的TCP的拥塞控制由"慢启动(Slow start)"和"拥塞避免(Congestio

TCP/IP 网络编程 (抄书笔记 1) -- TCP

TCP/IP 网络编程 (抄书笔记 1) – TCP TCP/IP 网络编程 (抄书笔记 1) – TCP Table of Contents server client 更好的 client 端实现 来源: <TCP/IP 网络编程> 抄书: 通信的双方都各自 拥有 输入缓存和输出缓存 socket 的 write 函数并不是立即传输数据, 而是写到输出缓存区, 到达另一端的输入缓存区 socket 的 read 函数调用的瞬间, 就从输入缓存区中读取数据 TCP 协议中的滑动窗口会保证 数

TCP/IP详解学习笔记

TCP/IP详解学习笔记(1)-基本概念 TCP/IP详解学习笔记(2)-数据链路层 TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议 TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节 TCP/IP详解学习笔记(6)-UDP协议 TCP/IP详解学习笔记(7)-广播和多播,IGMP协议 TCP/IP详解学习笔记(8)-DNS域名系统 TCP/IP详解学习笔记(9)-TCP协议概述 TCP

TCP/IP 网络编程 (抄书笔记 2) -- UDP

TCP/IP 网络编程 (抄书笔记 2) – UDP TCP/IP 网络编程 (抄书笔记 2) – UDP Table of Contents server client connect 来源: <TCP/IP 网络编程> 抄书: TCP 协议若要向 10 个客户端提供服务, 除了需要 listen 套接字外, 还需要 10 个服务器端套接字 (accept), 但是在 UDP 中, 不管是服务器端还是客户端都只需要 1 个套接字 udp 的 client 不需要 bind, 调用 sendt

TCP/IP 网络编程 (抄书笔记 4) -- 管道: 进程间通信

TCP/IP 网络编程 (抄书笔记 4) – 管道: 进程间通信 TCP/IP 网络编程 (抄书笔记 4) – 管道: 进程间通信 int fds[2]; pipe(fds); write(fds[1], buf, strlen(buf)); read(fds[0], buf, BUF_SIZE); 如果两个进程的通信只是 单纯的一方写, 然后另一方读 的情况, 那么 我们的管道操作没有问题, 但是: char str1[] = "str1"; char str2[] = "

TCP/IP 网络编程 (抄书笔记 3) -- 僵尸进程和多任务并发服务器

TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 Table of Contents 僵尸进程的产生 避免僵尸进程 信号 多任务的并发服务器 僵尸进程的产生 子进程先退出, 父进程没有退出 ==> 僵尸进程 父进程先退出, 子进程没有退出 ==> 子进程被 0 号进程回收, 不会产生僵尸进程 pid_t pid = fork(); if (pid == 0) { // child printf(&