0%

流量控制和拥塞控制

桃花坞里桃花庵,桃花庵下桃花仙;桃花仙人种桃树,又摘桃花卖酒钱。酒醒只在花前坐,酒醉还来花下眠;半醒半醉日复日,花落花开年复年。但愿老死花酒间,不愿鞠躬车马前;车尘马足富者趣,酒盏花枝贫者缘。若将富贵比贫贱,一在平地一在天;若将贫贱比车马,他得驱驰我得闲。别人笑我太疯癫,我笑他人看不穿;不见五陵豪杰墓,无花无酒锄作田。 —— 明.唐寅 《桃花庵歌》

TCP报文

一、前言

  1. TCP连接管理:TCP是面向连接的协议,每一个TCP连接都会经过三个阶段:连接建立、数据传送和连接释放。TCP连接的两个端口叫做套接字或插口,连接的建立采用客户/服务器方式,即C/S模式,主动发送连接建立的应用进程叫做客户机(client),而被动等待连接建立的应用程序叫做服务器(server)。

    • 面向连接的协议(Connection-oriented Protocol):会在通信计算机之间建立并维护一个连接,并且在通信过程中监视连接的状态。换句话说,通过网络传输的每个数据报都会有一个确认,发送计算机会记录状态信息来确保每个数据包都被正确接收了,并且根据需要重发数据。当数据传输结束之后,发送和接收计算机会以适当方式关闭连接。
  2. TCP连接建立(三次握手)

    • 客户机首先向服务器的TCP发送SYN=1,表示一个连接请求报文段,随机选择一个起始序号seq=x
    • 服务器的TCP收到连接请求报文段,如果同意建立连接,就像客户机发回确认ACK=1,并为该TCP连接分配TCP缓存和变量,并随机产生起始序号seq=y
    • 当客户机收到确认报文后,还要想服务器给出确认,并且也要给连接分配缓存和变量

服务端资源是在完成第二次握手分配的,而客户端资源是在完成第三次握手分配的,使得服务器易于收到SYN洪泛攻击。

  1. TCP连接释放(四次挥手)

    • 客户机打算关闭连接,向TCP发送FIN=1标志位的连接释放报文段,并停止再发送数据,seq=u等于前面已传送过的数据的最后一个字节的序号加1
    • 服务器疏导释放报文段,发出确认号ack=u+1,此时从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭
    • 若服务器已经没有向客户机发送的数据,就通知TCP释放连接,此时发送FIN=1的连接释放报文段
    • 客户机收到连接释放报文段后,必须发出确认ACK=1,确认号ack=w+1,序号seq=u+1。此时TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL(MSL=maxinum segment lifetime,最长报文生存时间)后才进入到连接关闭状态
  2. 重传机制,导致TCP对报文进行重传有两种情况:超时和冗余ACK

    • 超时:TCP每发送一个报文段就对这个报文段设置一次计时器,只要计时器设置的重传时间到期还没有收到确认就要重传这一报文段。而重传时间的计算采用了一种自适应算法,略大于加权平均往返时间RTTs
      • RTTs指的是一个报文段发出的时间到收到确认的时间之间的时间。
    • 冗余ACK:超时触发重传存在的一个问题就是超时周期过长,因此发送方通常可在超时事件发生之前通过所谓的冗余ACK来较好的检测丢包情况。
      • TCP规定当发送方收到对同一个报文段的3个冗余ACK时,就可以认为该报文段已经丢失。

    发送方A发送了序号为1,2,3,4,5的TCP报文段,其中2号报文在链路中丢失无法到达接收方B,因此3,4,5对B来说是失序报文段。TCP规定当期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。因此,当3,4,5报文到达B,并不是B期望收到的下一个报文,于是B就发送3个1号报文段的冗余ACK,表示自己期望接收2号报文段。这时A收到3个冗余ACK就判断2号报文段已经丢失,这时发送方A可以立即对2号报文执行重传,这种技术通常称为快速重传。

二、流量控制

  1. 接收端处理数据的速度是有限的,如果发送方的速度太快就会把缓冲区u打满。这个时候如果继续发送数据,就会导致丢包等一系列连锁反应。所以TCP支持根据接收端能力来决定发送端的发送速度,这个机制叫做流量控制。
    • 流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收
    • 也就是说流量控制是一个速度匹配服务,匹配发送方的发送速率和接收方的接收速率
  2. TCP使用滑动窗口机制来实现流量控制,其原理是:在通信过程中,接收方根据自己接收缓存的大小,动态调整发送方的发送窗口大小(即TCP报文段首部中的窗口字段swnd(send window))来限制发送方向网络注入报文的速率。 【同时,发送方根据其对当前网络拥塞程序的估计确定一个拥塞窗口cwnd(congestion window),最终A发送的窗口的实际大小是min(swnd,cwnd)值。】 这段属拥塞控制
    • 接收方每次收到数据包,在发送确定报文的同时告诉发送方自己的缓存区还剩余多少是空闲的,把接收方缓存区的剩余大小称之为接收窗口大小,用变量rwnd来表示
    • 接收端将自己可以接收的缓冲区大小放入TCP首部中的窗口字段,通过ACK端通知发送端;窗口大小字段越大,说明网络的吞吐量越高
    • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;发送端接受到这个窗口之后,就会减慢自己的发送速度
    • 如果接收端缓冲区满了就会将rwnd置为0,这时发送端不再发送数据
    • rwnd为0时发送端停止发送报文,并且同时开启一个定时器,每隔一段时间就发个窗口探测数据段去询问接收方否可以继续发送数据了
      • 如果接受窗口大小不为0,接收方就告诉发送方此时接受窗口的大小
      • 如果接受窗口大小为0,则发送方再次刷新启动定时器,重复上述步骤

流量控制
流量控制

三、拥塞控制

  1. 拥塞控制就是防止过多的数据注入到网络,这样使网络中的链路或路由器不至于过载。

  2. 发送方维持一个拥塞窗口cwnd的状态变量,它的大小取决于网络的拥塞程度,并且在动态的变化,发送方会让自己的发送窗口等于这个拥塞窗口。

  3. 发送方控制拥塞窗口的原则是:

    • 只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去
    • 但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数
  4. 拥塞控制的四种方法

    • 慢开始:在TCP刚连接好开始发送TCP报文段时,先令拥塞窗口cwnd=1,每经过一个传输轮次(即往返RTT),拥塞窗口cwnd就会加倍,呈指数形式增加。当慢开始算法把拥塞窗口cwnd增大到一个阈值ssthresh,改用拥塞避免算法。
    • 拥塞避免:发送端的拥塞窗口cwnd每经过一个往返RTT,cwnd=cwnd+1。

    只要发送方判断出网络拥塞,不论是在慢开始还是拥塞控制阶段,都要把慢开始门限值设置为出现拥塞时发送端窗口大小的一半,但不能小于2。然后把cwnd重新置为1,执行慢开始算法。这么做的目的是减少发送到网络中的分组数,使得发生拥塞的路由器能够有时间能把队列中积压的分组处理掉。

    发送端判断网络拥塞的依据: ①传送超时,即TCP重传定时器溢出 ②收到重复的确认报文

    • 快重传:要求接收方每收到一个失序的报文段后就立即发出重复确认,而不要等到自己发送数据时才进行捎带确认。发送方只要一连收到3个同样的确认报文就应当立即重传数据报,不必等待报文段的重传计时器到期。
    • 快恢复:当发送端收到连续三个冗余ACK时,就执行【乘法减少】算法,把慢开始阈值ssthresh设置为出现拥塞时发送方cwnd的一半。与慢开始将拥塞窗口cwnd设置为1的不同之处,它把cwnd的值设置为慢开始阈值ssthresh减半后的数值,然后执行拥塞避免算法,【加法增大】,使拥塞窗口缓慢线性增大。

快恢复