计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制

让TCP变得靠谱的机制

小林coding-TCP详解
客户端 == 发送端
服务端 == 接收端

1 重传机制

超时重传
  ①在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据,也就是我们常说的超时重传。
  ②超时重传时间 RTO(Retransmission Timeout 超时重传时间) 的值应该略大于报文往返 RTT(Round Trip Time) 的值。
  ③评估RTO的值,要对RTT进行加权平均,还要对RTT进行波动范围采样。重传时间是不断变化的,这个过程称为自适应重传算法(Adaptive Retransmission Algorithm)。

快速重传
  ①当服务端收到的报文段序号大于下一个期望的报文段序号时,就检测数据流中的一个间隔,然后发送3个冗余的ACK。客户端收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
  ②存在一个问题:重传的时候,是重传之前的一个,还是重传所有的问题。

SACK( Selective Acknowledgment 选择性确认)
  ①这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。

D-SACK (Duplicate SACK)
  ①使用了 SACK 来告诉「客户端」有哪些数据被重复接收了。
  ②可以让「客户端」知道,是发出去的包丢了,还是接收方回应的 ACK 包丢了,还是数据包被网络延迟了; 可以知道网络中是不是把「发送方」的数据包给复制了;

2 滑动窗口

累计确认
接收方发送ACK说某个ID之前的包都收到了,这种模式称为累计确认或者累计应答(Cumulative Acknowledgment)。

发送端滑动窗口
  ①TCP 头里有一个字段叫 Window,也就是窗口大小。这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。
  ②通常窗口的大小是由接收方的窗口大小来决定的。

计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制_第1张图片
图解:

  1. #1 是已发送并收到 ACK确认的数据:1~31 字节
  2. #2 是已发送但未收到 ACK确认的数据:32~45 字节
  3. #3 是未发送但总大小在接收方处理范围内(接收方还有空间):46~51字节
  4. #4 是未发送但总大小超过接收方处理范围(接收方没有空间):52字节以后 SND.WND:表示发送窗口的大小 SND.UNA:是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号。也就是#2的第一个字节。
  5. SND.NEX:一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号。也就是#3的第一个字节。
  6. 指向 #4的第一个字节是个相对指针,它需要 SND.UNA 指针加上 SND.WND 大小的偏移量,就可以指向 #4 的第一个字节了。

接收端滑动窗口

计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制_第2张图片
图解:

  1. #1 + #2 是已成功接收并确认的数据(等待应用进程读取);
  2. #3 是未收到数据但可以接收的数据;
  3. #4 未收到数据并不可以接收的数据;
  4. RCV.WND:表示接收窗口的大小,它会通告给发送方。
  5. RCV.NXT:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3 的第一个字节。
  6. 指向 #4的第一个字节是个相对指针,它需要 RCV.NXT 指针加上 RCV.WND 大小的偏移量,就可以指向 #4 的第一个字节了。

  ①接收窗口的大小是约等于发送窗口的大小的。因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系。

3 流量控制

为什么要流量控制?
  ①如果一直无脑的发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费。
  ②TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。

操作系统缓冲区与滑动窗口的关系
  ①发送窗口和接收窗口中所存放的字节数,都是放在操作系统内存缓冲区中的,而操作系统的缓冲区,会被操作系统调整。
  ②TCP 规定是不允许同时减少缓存又收缩窗口的,而是采用先收缩窗口,过段时间再减少缓存,这样就可以避免了丢包情况。

窗口关闭/死锁
  接收方向发送方通告窗口大小时,是通过 ACK 报文来通告的。
  当发生窗口关闭时,接收方处理完数据后,会向发送方通告一个窗口非 0 的 ACK 报文,如果这个通告窗口的 ACK 报文在网络中丢失了,会发生死锁。
计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制_第3张图片
死锁解决方案:
  TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。
  如果持续计时器超时,就会发送窗口探测 ( Window probe ) 报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。
计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制_第4张图片

  1. 如果接收窗口仍然为 0,那么收到这个报文的一方就会重新启动持续计时器;
  2. 如果接收窗口不是 0,那么死锁的局面就可以被打破了。

  窗口探测的次数一般为 3 次,每次大约 30-60 秒(不同的实现可能会不一样)。如果 3 次过后接收窗口还是 0 的话,有的 TCP 实现就会发 RST 报文来中断连接。

糊涂窗口综合症
  TCP + IP 头有 40 个字节,如果窗口很小,此时传输数据是得不偿失的。
  要解决糊涂窗口综合症,需要解决①让接收方不通告小窗口给发送方 ②让发送方避免发送小数据
解决方法见原文。

拥塞控制

为什么要进行拥塞控制,不是有流量控制吗?
  流量控制是避免「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么。
  在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大…

拥塞窗口 cwnd(congestion window)
  cwnd是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的。
  发送窗口的值是swnd = min(cwnd, rwnd)

TCP主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
  ①慢启动:当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1——指数增长。 举例:cwnd=2,发送2个,收到2个ACK,cwnd += 2 = 4。

  ②有一个叫慢启动门限 ssthresh (slow start threshold)状态变量。
  当 cwnd < ssthresh 时,使用慢启动算法。
  当 cwnd >= ssthresh 时,就会使用「拥塞避免算法」。
  拥塞避免:每当收到一个 ACK 时,cwnd 增加 1/cwnd——线性增长。 举例:cwnd = 16,发送16个,得到16个ACK,cwnd += 16 * (1/16) = 17。

  ③当拥塞发生,如果发生超时重传,ssthresh 设为 cwnd/2,cwnd 重置为 1。重新变成慢启动,造成网络卡顿。
  快速重传算法:发送三次前一个包的 ACK,发送端就会快速地重传。cwnd = cwnd/2,ssthresh = cwnd。

  ④快速恢复算法:快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。

  1. 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了)
  2. 重传丢失的数据包;
  3. 如果再收到重复的ACK,那么 cwnd 增加 1;
  4. 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh(快速重传时设置的) 的值,原因是该ACK 确认了新的数据,说明从 duplicated ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。

计算机网络③-③:TCP的重传机制、滑动窗口、流量控制(怎么发送死锁及解决方案)、拥塞控制_第5张图片
快速重传/恢复算法 没有像「超时重传」一夜回到解放前,而是还在比较高的值,后续呈线性增长。

③-③小结:
  ①顺序问题、丢包问题、流量控制都是通过滑动窗口来解决的,滑动窗口其实就相当于领导和下属的备忘录,布置过的工作要有编号,干完了有反馈,活不能派太多,也不能派太少。
  ②拥塞控制是通过拥塞窗口来解决的,相当于往管道里面倒水,快了容易溢出,慢了浪费带宽,要摸着石头过河,找到最优值,

你可能感兴趣的:(计算机网络,tcp/ip,网络,网络协议)