zoukankan      html  css  js  c++  java
  • TCP/IP学习笔记:TCP拥塞控制

    简介

    拥塞指的是

    在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。这种情况就叫拥塞(congestion)。

    TCP模块任务:提供网络利用率,降低丢包率,保证网络资源对每条数据的公平性。---- 拥塞控制

    标准文档:RFC 5681,介绍了拥塞控制4个部分:慢启动(slow start)、拥塞避免(congestion avoidance)、快速重传(fast retransmit)和快恢复(fast recovery)。

    拥塞控制for linux算法实现,有多种:reno算法、vegas算法、cubic算法等。部分或全部实现。
    查看方式(for Ubuntu 14):

    $ cat /proc/sys/net/ipv4/tcp_congestion_control
    cubic
    

    我的PC是采用cubic算法。


    术语介绍

    拥塞控制最终受控变量:发送窗口(SWND,Send Window)。也就是说,拥塞控制算法最终是通过控制SWND大小,来进行拥塞控制的。

    发送窗口

    在发送端发送缓存,存在4种类型数据,其中,发送窗口SWND是指(2)和(3)

    (1)已经发送并且对端确认(Sent/ACKed)---------------发送窗外 缓冲区外
    (2)已经发送但未收到确认数据(Sent/UnACKed)----------发送窗内 缓冲区内
    (3)允许发送但尚未发送的数据(Unsent/Inside)---------发送窗内 缓冲区内
    (4)未发送暂不允许(Unsent/Outside)-----------------发送窗外 缓冲区内
    

    发送缓存4种类别数据的示意图

    接收窗口

    接收窗口 指的是TCP报文头窗口字段,用于告诉发送端自己当前接收缓存大小。

    发送者最大段大小 SMSS

    MSS(Maximum Segment Size) TCP最大报文段长度(RFC 879),指的是每一个TCP报文段中的数据字段的最大长度。

    TCP报文段 = 数据字段 + TCP首部(20~40Byte)
    MSS = MTU - sizeof(TCPHDR) + sizeof(IPHDR)
    

    MTU:最大传输单元(含TCP头部、IP头部);TCPHDR:TCP报文头;IPHDR:IP报文头。

    MSS与MTU含义见下图:

    发送者最大段大小,称为SMSS(Sender Maximum Segment Size)。

    如何通告MSS?
    MSS的默认值是536byte,因此对端应能接受报文段长度是536 + 20(TCP固定首部) = 556byte的TCP报文。如果想要改变MSS,就需要在TCP连接时,通过TCP报文头可变长的选项(option)字段(1byte类型+1byte长度+不定长内容),告知对端。
    注意:MSS是设置好值后,再通告对方,而非与对方协商。

    SWND大小的影响

    如果SWND太小,会引起明显的网络延迟;反之,如果SWND太大,则容易导致网络拥塞。

    既然接收窗口RWND可以控制发送窗口,为何还需要拥塞控制,而不直接用接收窗口进行控制?
    虽然接收方可以通过接收通告窗口(RWND),来控制发送端SWND。但是接收方并不知道网络拥塞情况,无法针对网络情况进行控制。因此,发送端引入了一个称为拥塞窗口的(Congestion Windo, CWND)的状态变量。实际的SWND值是RWND和CWND中较小者。


    慢启动和拥塞避免

    慢启动

    TCP连接建立OK后,CWND初值IW(Initial Window),大小2~4SMSS -- 发送端最多能发送IW bytes数据。
    此后,发送端每收到接收端的一个确认,其CWND就按下式增加:

    CWND += min(N, SMSS), 其中,N是此次确认中包含的之前未被确认的字节数   (1) 
    

    这样,CWND将按指数形式扩大,这就是慢启动。
    慢启动算法理由:TCP模块刚开始发送数据时,并不知道网络的实际情况,需要一种试探的方式平滑地增加CWND的大小。

    慢启动门限

    如果不施加其他手段,慢启动必然使得CWND很快膨胀(慢启动并不慢),并最终导致网络拥塞。而慢启动门限(slow start threadhold size, ssthresh),就是这样一个限制:

    当cwnd < ssthresh时,使用慢开始算法;
    当cwnd > ssthresh时,停止慢开始算法,改用拥塞避免算法;
    当cwnd = ssthresh时,既可以用慢开始算法,也可以用拥塞避免算法;
    

    ssthresh初始值16。只要判断出现拥塞时,慢开始门限设为出现拥塞时发送窗口swnd的一半(但不能<2),然后把拥塞窗口cwnd重新设为1,执行慢开始算法。
    目的:迅速减少主机发送到网络中的分组数,使得发生拥塞时路由器有足够时间把队列中积压的分组处理完毕。

    拥塞避免算法

    CWND按线性方式增加,从而减缓其扩大。RFC 5681提到2种实现方式:
    1)每个RTT时间内,按(1)式计算新的CWND,而不论该RTT时间内发送端收到多少个确认。
    2)每收到一对新数据的确认报文段,就按式(2)来更新CWND。

    CWND += SMSS * SMSS / CWND                                        (2)
    

    下图粗略地描述了慢启动和拥塞避免发生的时机和区别。此外,我们假设当前ssthresh = 16SMSS大小(实际远不止这么大)

    慢启动和拥塞避免,都是发送端在未检测到拥塞时,所采用的积极拥塞避免的方法。下面介绍拥塞发生时(可能发生在慢启动阶段或拥塞避免阶段)拥塞控制的行为。

    发送端如何判断拥塞发生?

    • 传输超时,或者说TCP重传定时器溢出; ---- 拥塞避免
    • 接收到连续3个重复的确认报文; ---- 快速重传,快速恢复

    拥塞控制对这两种情况有不同的处理方式。第一种情况,仍然使用慢启动和拥塞避免;第二种情况,则使用快速重传和快速回复(如果真的发生拥塞)。

    如果发送端检测到拥塞发生是由于传输超时,即上述第一种情况,那么它将执行重传并做如下调整:

    ssthresh = max(FlightSize / 2, 2 * SMSS)             (3)
    CWMD <= SMSS
    

    其中,FlightSize是已经发送但未收到确认的字节数。这样调整后,CWMD将小于SMSS,那么必然小于新的慢启动门限值ssthresh(根据式(3),ssthresh一定不小于SMSS的2倍),故而拥塞控制再次进入慢启动阶段。

    何为TCP超时重传?
    TCP服务必须能够重传超时时间内未收到确认TCP报文段。为此,TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动。如果超时时间内未收到对方的应答,TCP模块将重传TCP报文段并重置定时器。

    所谓超时,是指定时器 > 最大往返时间RTT。
    RTT是指一个数据报发送到目的地,然后到发送方收到确认所需的时间,这是测量RTT。发送报文和确认报文并非数量上的一一对应,可能发送多次,确认一次,也可能是一一对应。


    快速重传和快速恢复

    如何通过接收到重复的确认报文段,判断网络是否真的发生拥塞?
    发送端接收到重复的确认报文段可能情形:TCP报文段丢失,接收端收到乱序TCP报文段并重排等。

    拥塞控制算法需要判断当收到重复的确认报文段时,网络是否真的发生了拥塞,或者说TCP报文段是否真的丢失了。具体做法:
    发送端如果连续收到3个重复的确认报文段,就认为拥塞发生了。然后它启用快速重传和快速恢复算法来处理拥塞,过程如下:

    1)当收到第3个重复的确认报文段时,按(3)式计算ssthresh,然后立即重传丢失的报文,而不是等到重传计时器超时,这称为快速重传。并按式(4)设置CWND

    CWND = ssthresh + 3 * SMSS                             (4)
    

    2)每次收到1个重复的确认时,设置CWND = CWND + SMSS,而非从慢开始算法的cwnd=1开始。此时,发送端可以发生新的TCP报文段(如果新的CWND允许的话)

    3)当收到新数据的确认时,设置CWND = ssthresh(ssthresh是新的慢启动门限值,由第一步计算得到)

    步骤1)称为快速重传,步骤2)3)称为快速恢复。快速重传和快速恢复完成之后,拥塞控制将恢复到拥塞避免阶段。这点由第3)步操作可得知。


    总结

    拥塞控制对象:发送窗口SWND. SWND <= min(RWND, CWND)
    网络出现超时 => 采用慢开始算法 + 拥塞避免算法;
    网络出现重传 => 快速恢复算法;


    参考

    [1]谢希仁. 计算机网络.第5版[M]. 电子工业出版社, 2008.
    [2]游双. Linux高性能服务器编程[M]. 机械工业出版社, 2013.
    [3]Postel J . Transmission control protocol; rfc793[J]. Rfc, 1981.(RFC793)
    [4]Тезисы, Статусдокумента, Авторскиеправа, et al. RFC 5681 TCP Congestion Control. 1996.(RFC5681)

  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/fortunely/p/15042222.html
Copyright © 2011-2022 走看看