TCP特性
如何保证数据不丢失的
TCP拥有8大特性来保证稳定性)(1.确认应答,2.超时重传,3.连接管理,4.流量控制,5.拥塞控制)以及其性能(1.滑动窗口,2.捎带应答,3.延时应答)。
# 确认应答
TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。 也就是发送ACK报文。 这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。
序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。
序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一
# 超时重传
在确认应答的前提下,如果发起方迟迟没有收到相应的ack,这是不合理的。
那么没有收到ack的原因是什么呢?
- 发送方问题:发送的数据全体丢包,接受方从头到尾没有接受到数据
- 接受方问题:接受方成功收到了数据,但是因为网络原因,ack没有发送成功
这时候就会进行超时重传
如果是发送方的问题,因为是长时间没有收到ack,超时后会重复发送数据,接收方判断序列号是要接受的数据,接受后返回ack。
如果是接收方问题,那么发送方这边迟迟没有收到ack,会重新发送数据,接收方判断序列号,因为已经接受过该数据,所以会直接抛弃该数据,返回最后需要的ack。
# 连接管理
三握手四挥手
# 流量控制
发送缓冲区:将要发送的数据都会先放在一个缓冲区里
接受缓冲区:接受数据时会先存放在一个缓存区中,如果缓存区满了,另外发送过来的数据就会被丢弃。
接收端在接收到数据后,对其进行处理。如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。
接收端在接收到数据后,对其进行处理。如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。
在TCP协议的报头信息当中,有一个16位字段的窗口大小。在介绍这个窗口大小时我们知道,窗口大小的内容实际上是接收端接收数据缓冲区的剩余大小。这个数字越大,证明接收端接收缓冲区的剩余空间越大,网络的吞吐量越大。接收端会在确认应答发送ACK报文时,将自己的即时窗口大小填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值的改变进而改变自己的发送速度。如果接收到窗口大小的值为0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段(持续计数器),让接收端把窗口大小告诉发送端。
持续计数器:防止窗口大小为0时的死锁。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。
本质:防止分组丢失
# 拥塞控制
# 问题引出
TCP传输的过程中,发送端开始发送数据的时候,如果刚开始就发送大量的数据,那么就可能造成一些问题。网络可能在开始的时候就很拥堵,如果给网络中在扔出大量数据,那么这个拥堵就会加剧。拥堵的加剧就会产生大量的丢包,就对大量的超时重传,严重影响传输。
所以TCP引入了慢启动的机制,在开始发送数据时,先发送少量的数据探路。探清当前的网络状态如何,再决定多大的速度进行传输。这时候就引入一个叫做拥塞窗口的概念。发送刚开始定义拥塞窗口为 1,每次收到ACK应答,拥塞窗口加 1。在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。
拥塞窗口的增长是指数级别的。慢启动的机制只是说明在开始的时候发送的少,发送的慢,但是增长的速度是非常快的。为了控制拥塞窗口的增长,不能使拥塞窗口单纯的加倍,设置一个拥塞窗口的阈值,当拥塞窗口大小超过阈值时,不能再按照指数来增长,而是线性的增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。
# 详细说明
# 慢开始
慢开始的主要目的就是先去探测网络是否拥塞,如果不拥塞则快速扩大拥塞窗口。
拥塞窗口cwnd从大小1开始,每经历一个RRT时间,拥塞窗口的大小则翻倍。但是也不能进行无限的翻倍,因为过大就会导致过多的数据流动到网络中,会引起网络的拥塞。所以我们必须设置一个阈值ssthresh。
当cwnd<ssthresh时,使用慢开始算法。 当cwnd>ssthresh时,改用拥塞避免算法。 当cwnd=ssthresh时,慢开始与拥塞避免算法任意
注意:这里的慢开始并不是开始得很慢,而是开始时cwnd很小为1。其增长速度是非常快的。
# 拥塞避免
核心:当拥塞窗口的大小超过了阈值后,让其大小每经过一个RRT时+1,即线性增加,
但是,一旦发现网络当中出现拥塞,就必须马上做出避免拥塞的操作:将阈值置为当前拥塞窗口的一半,然后将拥塞窗口置为1,这样可以快速的在发现网络拥塞后,将自己发送的数据范围到最小。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
拥塞控制和流量控制有什么区别
- 拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:( 1 )慢开始、拥塞避免( 2 )快重传、快恢复。
- 流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
# 快重传
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。如下图:
# 快恢复
快重传配合使用的还有快恢复算法,有以下两个要点:
当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半(为了预防网络发生拥塞)。但是接下去并不执行慢开始算法 考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,使cwnd缓慢增大。如下图:TCP Reno版本是目前使用最广泛的版本。
注意:在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用