TCP为什么可靠

https://blog.csdn.net/Awille/article/details/79748193
https://www.jianshu.com/p/ff36b6ab503e

1 序列号与确认号

ACK机制
由于通信过程的不可靠性,传输的数据不可避免的会出现丢失、延迟、错误、重复等各种状况,TCP协议为解决这些问题设计了一系列机制。
这个机制的核心,就是发送方向接收方发送数据后,接收方要向发送方发送ACK(回执)。如果发送方没接收到正确的ACK,就会重新发送数据直到接收到ACK为止。比如:发送方发送的数据序号是seq,那么接收方会发送seq + 1作为ACK,这样发送方就知道接下来要发送序号为seq + 1的数据给接收方了。
在这里插入图片描述ACK机制是怎么工作的:
a 数据丢失或延迟。发送方发送数据seq时会起一个定时器,如果在指定时间内没有接收到ACK seq + 1,就把数据seq再发一次。

b 数据乱序。接收方上一个收到的正确数据是seq + 4,它返回seq + 5作为ACK。这时候它收到了seq + 7,因为顺序错了,所以接收方会再次返回seq + 5给发送方。

c 数据错误每一个TCP数据都会带着数据的校验和。接收方收到数据seq + 3以后会先对校验和进行验证。如果结果不对,则发送ACK seq + 3,让发送方重新发送数据。

d 数据重复。接收方直接丢弃重复的数据即可。

ACK的优化
按照ACK机制,只要整个数据传输顺利结束,接收方就能收到完整有序的数据了。但是,如果我们针对每一个数据包都发送ACK,就会有大量的网络资源消耗在ACK的发送上,这不太划算的。于是,TCP设计了延迟ACK的机制。

这个机制其实很简单。客户端一次给服务器发送多个数据包,当服务器收到客户端的数据包时,不马上发送ACK,而是稍微等一小段时间。在这个过程中服务器可能能收到后续几个数据包,服务器就可以直接按照最后一个正确的数据发送ACK,减少发送ACK的总数

当发送错误的时候,会发生:
a、超时重传机制
发送方发送的报文中含有序列号,每当发送一个报文后,就启动一个计时器(RTO),该计时器的时间一般是有当前网络来决定的,一个RTT指的是当一个报文从发送到接收到对应的ACK标志的时间,RTO的决定一般是发送方尝试发送几个报文,然后取平均RTT时间来决定计时器的值。 当发送一个报文以后,发送方在计时范围以内,如果没有接收到相应的ACK确认报文,那么发送方就会重传该报文。

b、快速重传机制
该机制指的是,发送方一直发送报文,不会每发一次报文就都要等待到这个报文的ACK标志才发送下个报文。 当接收方发送接受的序列号不对的时候,发送连续的3个ACK标志,告诉发送方,这个报文在传输过程中出现了丢包。发送方如果接收到某个相同序列号的三个ACK报文,那么此时立马重发该报文,不用等待计时器的时间结束。

2 流量控制(滑动窗口)

发送方通过维持一个发送滑动窗口来确保不会发生由于发送方报文发送太快接收方无法及时处理的问题。此时发送方的报文分为四类第一类是已经发送并且得到接收方确认的报文,第二类是已经发送但是没有接收到确认的报文,第三类是发送方还没发送,但是滑动窗口还足够巨大,允许被发送的报文, 第四类是还没发送并且窗口已经被占满,不允许发送的报文。 一般来说,滑动窗口的最左端都是介于第一类跟第二类报文的分界线,最右端是第三类跟第四类报文的分界线。

滑动窗口的流量控制可以包括那么几个协议
a、停等协议。 滑动窗口的大小为1, 每个发送报文都要等到被确认以后,发送方才继续发送下一个报文。

扫描二维码关注公众号,回复: 5500139 查看本文章

b、后退n步协议。 该协议下,滑动窗口大于1,发送方可以一直发送报文,但是当接收到接收方发送的三个连续的同一序列号的ACK报文时,说明该序列号的报文是已经丢失的,那么此时重发该丢失报文以及该报文以后的报文(包括那些已经发送的)。

c、选择重传。在后退n步协议当中,如果某个报文丢失。那么将要重新发送这个丢失报文及以后的所有报文(包括已经发送的),选择重传协议不用做此要求,只要重新发送丢失的报文即可。

…(其实还有几种协议,我这里就不继续说了)

3 拥塞控制

首先要明白拥塞控制与流量控制有什么不同,流量控制考虑的是单纯的发送方与接收方,这两个在全部网络过程中的两个端点而拥塞控制考虑的是整个网络。可以想象一下,在流量控制当中,接收方跟发送方考虑的只是自己的报文有没有发送并且被接收的问题,假设现在网络阻塞,在超时重传机制当中,发送方没有发送后在计时器时间内没有接收到确认报文,就立马重新发送报文,这时候对已经拥塞的网络来说,无异于雪上加霜。同样实在拥塞的网络情况下,考虑下快速重传机制,同样是这个道理。所以,针对以上问题,TCP应该要有一个拥塞控制机制,不然,后果不堪设想。

在拥塞控制机制当中,发送方会维护一个滑动发送窗口,该窗口与拥塞控制窗口一般是一样大的,除非受到物理限制,假设网络的承载量是无线的,那么拥塞窗口理论上就可以无限增大,但受现在电脑技术限制,我们可能无法将发送窗口与拥塞窗口变得一样大

下面说明下几个符号说明:

  • cwnd:拥塞窗口大小
  • ssthreshold: 拥塞阈值 (该阈值是对网络状况的一个预估,决定在拥塞窗口多大的时候采取怎样的策略,它的初始化一般是一个估计,一般都会给出)

现在可以看下这个拥塞控制机制包括哪几个策略

a、慢启动
此时一般是(记住是一般情况)cwnd<ssthreshold,此时cwnd呈指数形式增长,1、2、4、8、16、32…这种增长趋势

b、拥塞避免
此时一般cwnd>ssthreshold,此时cwnd呈线性增长,32、33、34、35…这种增长趋势

c、拥塞解决
此时一般是遇到了网络拥塞的状况,解决方法是拥塞阈值乘性减即ssthreshold=cwnd/2,cwnd=1,或者ssthreshold=cwnd/2,cwnd=ssthreshold,这两种情况在后面说明

d、快速恢复
一般是启用拥塞结局策略之后根据不同的情况进入慢启动或者拥塞避免阶段

4 下面我们模拟一下发送方发送报文:假设ssthreshold=8

首先肯定是慢启动阶段,cwnd增长,1、2、4、8,到8的时候,cwnd达到了ssthreshold的值,于是进入拥塞避免阶段,cwnd继续增长8、9、10,假设到10的时候,发生了网络拥塞,这时候拥塞分为两种情况

第一种,发送方接收到同一序列号的报文的连续三个ACK确认报文,说明出现了丢包,但是接收到接收方发送的丢包信号,说明网络情况还是相对较好的,于是此时发送方做出反应,将ssthreshold=cwnd/2=5,cwnd=ssthreshold=5,然后进入拥塞避免阶段,cwnd继续以5、6、7…这种情况增长。

第二种,发送方接收到同一序列号的报文连续两个ACK确认报文,这时候,就说明网络拥塞情况就比较严重了,连接收方发送的丢包信号都不完整了,这个时候得采取更加严厉的措施了,于是ssthreshold=cwnd/2,cwnd=1,然后重新进入慢启动过程。

猜你喜欢

转载自blog.csdn.net/csdnlijingran/article/details/88385733