网络-07-TCP传输控制

1,481 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

TCP传输控制

上一节介绍了TCP连接的建立,本节将围绕TCP连接建立后,TCP的传输控制,包括可靠性传输,流量控制和拥塞控制,了解TCP是如何实现这些功能的。

可靠传输

之前讲到UDP是不可靠传输,而TCP是可靠传输,那么TCP是如何保证数据可靠传输的呢?

TCP可靠传输依靠ARQ,也就是停止等待协议。停止等待,就是指在发送一个包后需要等待对方的回复报文才会继续往下发,否则的话会停止等待。如果等待一段时间后没有收到确认报文,那么就会超时重传刚刚发送的数据包。以此来保证不会发生丢包。如果重传多次仍然没有收到回复报文,那么发送方将会发送RST报文。

如果是延迟收到确认报文的话,发送方会丢弃重复的确认。同样的如果是由于回复报文丢失导致的发送方没有收到回复报文,发送方重复发送数据包的话,接收方会丢弃该数据包,并且重传确认报文。

但是如果一个一个包发再等待对方确认的话速度就太慢了,那么在TCP实际传输中通常是一次性发多个包,那么如果发的多个包其中一个包丢失了怎么办呢?

如果按照正常来说,比如1,2,3,4,5这五个包同时发送,数据包3丢失了,那么server会发送ACK 2的报文,那么345的报文都需要重发,但是45的数据包并没有丢失,就导致了资源的浪费,要解决这个问题就需要SACK技术。

SACK

SACK是指选择性确认,在发生丢包时,它会告诉发送方自己收到了什么数据,具体的实现用到了TCP首部的选项部分。

截屏2023-01-09 21.16.49.png

Kind占1字节,值为5时代表为SACK选项。Length占1字节,表示SACK选项一共占几字节。

下面的Left Edge和Right Edge表示SACK的左右边界,各占4字节,两个一组。之前我们知道TCP选项最大只有40个字节,而SACK一组需要8个字节,因此最多只能携带四组边界信息。

截屏2023-01-09 21.58.05.png

如图,发送方一共发送了五个包,但是第三个包出现了丢失,那么在接收方返回确认报文时,确认号为200即编号200以下的报文都接收成功,SACK为400~600也就是这一个区间的报文也接收成功了,那么发送方就知道中间的300~399丢失了,重发丢失信息后返回确认报文600。

流量控制

刚刚提到发送方一次性会发送多个数据包,但是这个数据包并不是说想发多少就发多少,这就是TCP连接的流量控制。

如果接收方的接收缓冲区满了,发送方再发送数据包数据包那么接收方会把数据包丢弃,造成极大的网络资源浪费。

在TCP报文头中有窗口字段,这个字段记录了双方窗口的大小,一般来说窗口的大小由接收方决定,接收方需要告诉发送方缓冲区还有多少大小能够接收数据,发送方发送的数据不能大于这个大小。

但是流量控制同样会出现一些问题,如果窗口为0,那么发送方就不会发送数据,直到接收到窗口不为0的报文。那么如果这个报文丢失了,发送方就会一直等待窗口不为0的报文,接收方等待发送方的报文,造成死锁。为了避免这一种情况的发生,发送方在接收到窗口0报文后,会设置计时器,一段时间后发送试探报文,如果仍然窗口为0则重置计时器,如果多次重发仍然没有收到回复报文,则会发送RST。

同时还会出现糊涂窗口的问题,我们知道一个数据包封装报文头是很长的,如果说窗口只有几个字节就发送数据,那么就会造成极大的浪费。为了避免这种情况,可以从接收方的角度不通告小窗口,当缓冲区大小小于MSS与1/2缓存大小的最小值时则通告窗口为0。同时也可以从发送方的角度,如果窗口过小或者数据过小则囤积数据。

拥塞控制

当网络出现拥塞时,继续发送数据包会出现数据包的时延甚至丢包,拥塞控制就是为了解决这个问题。

在拥塞控制中,发送方维护了一个状态变量,称为拥塞窗口cwnd,上一节的流量控制谈到窗口的大小由接收方决定,接收方窗口为rwnd,那么最终发送的数据swnd=min(cwnd,rwnd)。cwnd的变化分为四个部分。

截屏2023-01-10 23.10.06.png

第一个阶段为慢启动,cwnd其实较小,但是会以指数级增长,以上图举例的话,一开始的cwnd为1MSS,下一轮则为2MSS,在下一轮为4MSS。当到达慢启动门限时ssthresh时就会进入下一阶段,如上图的门限值是8MSS。

第二个阶段为拥塞避免,在这个阶段cwnd进入线性增长,每收到一个ACK报文,cwnd将增加1/cwnd。比如说刚进入8MSS的门限值,那么在收到8个ACK报文后,cwnd会增长到9MSS。

一旦出现网络丢包的现象,表明网络出现了拥塞,如上图所示是直接将cwnd变为初始化值,并且将门限值变为发生拥塞时的cwnd的一半,图上的这种情况就是门限值变为6MSS。这种方式被称为乘法减小,但是这种方式过为激进,网络上的感知会很强,并且在频繁的阻塞后会门限值会降得很低。

截屏2023-01-11 01.30.06.png

这种方式就是快重传,在收到三个重复的ACK时,就证明我们出现丢包了,那么我们就需要将cwnd变为一半,同时将门限值设定为这一半的cwnd,然后再次进入拥塞避免状态。这就意味着我们尝试通过降低拥塞窗口来降低网络的压力,来尝试能否重传丢失数据,如果我们再次收到了三个重复的ACK,那么我们将继续降低cwnd和门限值。

总结

本节介绍了TCP连接建立后的传输控制,包括可靠传输,流量控制和拥塞控制,这代表着TCP连接建立后是有自我调节能力的,不仅仅可以保证数据的传输,还可以自主优化传输过程。

感谢观看!