TCP如何保证可靠传输和流量控制

Posted by RussXia on April 16, 2020

流量控制与滑动窗口

  • 虽然发送方的发送窗口是根据接受方的接受窗口指定的,但是发送方的窗口,并不一定等于接收方的接受窗口
    • 网络传送窗口值存在一定的时间滞后,且这个过程中发送方可能依然在用老的窗口发送数据。
    • 发送方可能发生拥塞,此时发送方可能会适当减小自己的发送窗口
  • 对于不按序达到的TCP报文如何处理,TCP并没有明确规定。
    • 如果接收方把不按序到达的数据一律丢弃,那么发送方会重复发送数据。
    • TCP通常做法是:将不按序到达的数据临时缓存在接受窗口中,等接受到缺失的数据,再交付给上层应用。
  • TCP要求接收方必须有累计确认和捎带确认机制,接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上(TCP是全双工通信)
    • 接收方不应过分推迟发送确认,否则会到导致发送方的超时重传,反而浪费了网络资源
    • 捎带确认并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据
  • TCP通信是全双工通信。通信过程中每一方都有可能在发送数据和接受数据。因此,每一方都有自己的发送窗口和接受窗口,在谈这些窗口时,一定要弄清是哪一方的窗口。

拥塞控制

  • 某段时间内,若对网络中某一资源的需求超过了该资源所能提供的部分,网络性能就会变坏。这种情况就叫做拥塞
  • 出现拥塞而不进行控制,整个网络的吞吐量将随输入的负荷增大而下降

为了避免出现拥塞的情况,TCP使用了四种算法来实现拥塞控制:1.慢开始(slow start) 2.拥塞避免(congestion avoidance) 3.快速重传(fast retransmissionmit) 4.快速恢复(fast recovery)

慢开始

  • 发送方维护一个叫做拥塞窗口cwnd的状态变量,其值取决于网络的拥塞程度,并且动态变化
    • 拥塞窗口cwnd的维护原则:只要网络没有出现拥塞,拥塞窗口就增大一些(1->2->4->8…)。如果网络出现拥塞,拥塞窗口就减少一些
    • 判断是否出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生超时重传)
  • 发送方将拥塞窗口作为发送窗口swnd,即swnd=cwnd(发送窗口=拥塞窗口)
  • 维护一个慢开始门限sshtresh状态变量:
    • 当cwnd<sshtresh时,使用慢开始算法
    • 当cwnd>sshtresh时,停止使用慢开始算法,改用拥塞避免算法。
    • 当cwnd=sshtresh时,既可以使用慢开始算法,也可以使用拥塞避免算法。

拥塞避免

当达到慢开始门限sshtresh时,转而开始采用拥塞避免算法。使用拥塞避免算法,cwnd将线性增加(16->17->18…)。当发生超时重传时,会判定网络可能出现了拥塞,会进行以下工作。

  • 将sshtresh设置为当前cwnd的一半
  • 将cwnd设置为1,重新开始开始执行慢开始算法。

快速重传

有时,个别报文段会在网络中丢失,但实际上网络并没有发生拥塞。这将导致发送方超时重传,并误认为发生了网络拥塞。发送方此时会将拥塞窗口cwnd又设置为1,并且错误地启动慢开始算法,因而降低了传输效率

快重传算法就是让发送方尽早知道发生了个别报文段的丢失,使发送方尽快重传,而不是等待超时重传计时器超时再重传。

  • 要求接受方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认
  • 即使收到了失序的报文段,也要立即发出对已收到报文段的重复确认
  • 发送方一旦收到3个连续的重复确认,就讲相应的报文段立即重传,而不是等待该报文段的超时重传计时器超时再重传。

快速恢复

发送方一旦收到3个连续的重复确认,会知道发生了部分报文段丢失。于是不启动慢开始算法,而执行快速恢复算法

  • 发送方将慢开始门限sshtresh拥塞窗口cwnd调整为当前窗口的一半开始执行拥塞避免算法
  • 也有的快恢复实现方式,是把快恢复开始时的拥塞窗口值在增大一些,即等于新的sshtrsh+3

image-20200415142345962