TCP可靠传输的原理及其实现

可靠传输的工作原理

理想的传输条件有以下两个特点:
1.传输信道不产生差错
2.不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据。
然而实际的网络不具备以上两个条件。但我们可以使用一些可靠的协议,当出现差错时让发送方重传出现错误的数据,及时告诉发送方适当降低发送数据的速度。这样一来,本来不可靠的传输信道就能够实现可靠的传输了。

1.停止等待协议

就是每发送完一个分组就停止发送,等待对方确认。在收到确认后再发送下一个分组。

确认和重传机制

出现差错时,没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就是超时重传。要实超时重传,就要在每发送完一个分组时设置超时计时器。如果在超时计时器到期之前收到对方确认,就撤销已设置的超时计时器。

像上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。这种可靠传输协议我们称为自动重传ARQ。意思是重传的请求是自动进行的。接受方不需要请求发送方重传某个出错的分组。

停止等待协议简单,但是缺单是信道利用率太低。但使用流水线传输时,就要使用连续的ARQ协议和滑动窗口协议。

2.利用ARQ协议和滑动窗口协议的实现方式

TCP的流量控制

先了解TCP 滑动窗口
TCP 滑动窗口分为两种: 发送窗口和接收窗口。

发送窗口:

发送端的滑动窗口结构如下:
在这里插入图片描述
其中包含四大部分:

  • 已发送且已确认
  • 已发送但未确认
  • 未发送但可以发送
  • 未发送也不可以发送
    在这里插入图片描述
    发送窗口就是图中被框住的范围。SND 即send, WND 即window, UNA 即unacknowledged, 表示未被确认,NXT 即next, 表示下一个发送的位置。

接收窗口:
在这里插入图片描述
REV 即 receive,NXT 表示下一个接收的位置,WND 表示接收窗口大小。j蓝色部分为:允许接受的窗口。

流量控制过程

这里我们不用太复杂的例子,以一个最简单的来回来模拟一下流量控制的过程,方便大家理解。

首先双方三次握手,初始化各自的窗口大小,均为 200 个字节。

假如当前发送端给接收端发送 100 个字节,那么此时对于发送端而言,SND.NXT 当然要右移 100 个字节,也就是说当前的可用窗口减少了 100 个字节,这很好理解。

现在这 100 个到达了接收端,被放到接收端的缓冲队列中。不过此时由于大量负载的原因,接收端处理不了这么多字节,只能处理 40 个字节,剩下的 60 个字节被留在了缓冲队列中。

注意了,此时接收端的情况是处理能力不够用啦,你发送端给我少发点,所以此时接收端的接收窗口应该缩小,具体来说,缩小 60 个字节,由 200 个字节变成了 140 字节,因为缓冲队列还有 60 个字节没被应用拿走。

因此,接收端会在 ACK 的报文首部带上缩小后的滑动窗口rwnd 140 字节,发送端对应地调整发送窗口的大小为 140 个字节。

此时对于发送端而言,已经发送且确认的部分增加 40 字节,也就是 SND.UNA 右移 40 个字节,同时发送窗口缩小为 140 个字节。

这也就是流量控制的过程。尽管回合再多,整个控制的过程和原理是一样的。

TCP的拥塞控制

所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不致过载。

对于拥塞控制来说,TCP 每条连接都需要维护两个核心状态:

  • 拥塞窗口(Congestion Window,cwnd)
  • 慢启动阈值(Slow Start Threshold,ssthresh)

涉及到的算法有这几个:
慢启动、拥塞避免、快速重传和快速恢复

接下来,我们就来一一拆解这些状态和算法。首先,从拥塞窗口说起。

拥塞窗口
拥塞窗口(Congestion Window,cwnd)是指目前自己还能传输的数据量大小。

那么之前介绍了接收窗口的概念,两者有什么区别呢?

  • 接收窗口(rwnd)是接收端给的限制
  • 拥塞窗口(cwnd)是发送端的限制

限制谁呢?限制的是发送窗口的大小。有了这两个窗口,如何来计算发送窗口?

发送窗口大小 = min(rwnd, cwnd)
取两者的较小值。而拥塞控制,就是来控制cwnd的变化。

1.慢启动和拥塞避免

慢启动

由于一开始不清楚网络的符负荷情况,所以如果立即把大量数据字节注入网络,那么就可能引起网络发生拥塞。所以,由小到大逐渐增大发送窗口 一开始cwnd=1(目的探测一下网络情况),每经过一个传输轮次RTT,拥塞窗口cwnd就加倍。

拥塞避免:

为了防止拥塞窗口cwnd增长过大引起网络拥塞,还要设置一个慢开始门限(ssthresh) 状态变量
拥塞避免就是让拥塞窗口cwnd缓慢地增大,每进过一个RTT就把cwnd+1.这表明在拥塞避免阶段,cwnd按线性规律缓慢增大,比慢开始算法的拥塞窗口增长速率缓慢得多。

2.快重传和快恢复

快重传:

发送方只要一连收到3个重复确认,就知道接受方确实没有收到某个包,因次立即进行重传,不用等到一个 RTO 的时间到了才重传。

选择性重传

那你可能会问了,既然要重传,那么只重传第 5 个包还是第5、6、7 个包都重传呢?
当然第 6、7 个都已经到达了,TCP 的设计者也不傻,已经传过去干嘛还要传?干脆记录一下哪些包到了,哪些没到,针对性地重传。

通过left edge和right edge(左边界指出字节快的第一个字节序号,有边界减1才是字节块中的最后一个字节块的序号)告知发送端已经收到了哪些区间的数据报。因此,即使第 5 个包丢包了,当收到第 6、7 个包之后,接收端依然会告诉发送端,这两个包到了。剩下第 5 个包没到,就重传这个包。

如果要使用选择确认SACK,那么在建立TCP连接时,就要在TCP首部得选项中加上‘允许SACK’的选项,这而且双方必须事先约定好。这个过程也叫做选择性重传(SACK,Selective Acknowledgment),它解决的是如何重传的问题。

快速恢复:
当然,发送端收到三次重复 ACK 之后,发送方知道现在只是丢失了个别包,觉得现在的网络已经有些拥塞了,于是不启动慢开始,而是执行快恢复。

在这个阶段,发送端如下改变:

  • 拥塞阈值降低为 cwnd 的一半
  • cwnd 的大小变为拥塞阈值
  • cwnd 线性增加(即执行拥塞避免算法)

猜你喜欢

转载自blog.csdn.net/HZ___ZH/article/details/113553044