TCP/IP总结(重传,Nagle算法,滑动窗口,拥塞控制)

TCP是如何保证可靠传输的

为了保证可靠传输,TCP比UDP多了很多控制协议和算法。

  • 连接管理——3次握手和4次握手
  • 数据破坏——通过校验和
  • 丢包——应答与超时重发机制
  • 分片乱序——序列号
  • 窗口滑动——提高发送效率,对发送端和接收端流量进行控制
  • 加快通信速度——快速重发,三次收到重发消息进行重发
  • 流控制——避免网络流量浪费
  • 拥塞控制——慢启动算法,拥塞窗口

TCP的重传机制

TCP是可靠的传输协议,意味着必须按序,无差错的传送数据和目的端。通过校验和,确认应答,重传来保证。校验和应答已经介绍过,这里主要讲解重传机制。重传分为两种:超时重传和快速重传。

  1. 超时重传:数据丢失,当定时器超时时,将重传具有最小序号但仍未应答的报文段,并将超时间隔设为先前的两倍。当收到上层应用的数据和收到ACK时,超时时间将重新计算。
  2. 快速重传:当发送方接受到3个冗余ACK时,执行重传。
    冗余ACK:当接受方接受到比期望序号大的失序报文段到达,检测出间隔时,立即发送冗余ACK,指示下一个期待字节的序号(其为间隔的低端的序号)。
    在这里插入图片描述

经受时延的确认应答

当一个期望的序号报文到达,延时等待一段时间,如果在这段时间内有新的期望的序号报文到达,则立即发送单个累计ACK,以确认两个按序报文段。如果超时,则发送一个ACK。

Nagle算法

TCP是基于流的传输协议,在Rlogin和Telnet传输中会出现只有一个字节数据的TCP数据包。而一个TCP数据包的首部加上IP首部就有40个字节,很显然发这样的数据包划不来。为了减少这样的数据包,有人提出了Nagle算法。

Nagle算法简单讲就是,等待服务器应答包到达后,再发送下一个数据包。数据在发送端被缓存,如果缓存到达指定大小就将其发送,或者上一个数据的应答包到达,将缓存区一次性全部发送。

Nagle算法是从发送端角度考虑减少了数据包的个数,时延应答从接收端角度考虑减少了数据包的个数。

注意:我以前一直理解为只有上一个数据的应答包到达时才发送数据,但有一个前提条件是发送缓冲区中的数据大小不足一个MSS时,当数据超过一个MSS时,直接发送报文段。

滑动窗口(流量控制)

1)TCP滑动窗口分为接受窗口,发送窗口
滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。
对ACK的再认识,ack通常被理解为收到数据后给出的一个确认ACK,ACK包含两个非常重要的信息:

  • 一是期望接收到的下一字节的序号n,该n代表接收方已经接收到了前n-1字节数据,此时如果接收方收到第n+1字节数据而不是第n字节数据,接收方是不会发送序号为n+2的ACK的。举个例子,假如接收端收到1-1024字节,它会发送一个确认号为1025的ACK,但是接下来收到的是2049-3072,它是不会发送确认号为3072的ACK,而依旧发送1025的ACK。
  • 二是当前的窗口大小m,如此发送方在接收到ACK包含的这两个数据后就可以计算出还可以发送多少字节的数据给对方,假定当前发送方已发送到第x字节,则可以发送的字节数就是y=m-(x-n).

这就是滑动窗口控制流量的基本原理

重点:发送方根据收到ACK当中的期望收到的下一个字节的序号n以及窗口m,还有当前已经发送的字节序号x,算出还可以发送的字节数。

1)对于TCP会话的发送方,任何时候在其发送缓存内的数据都可以分为4类,“已经发送并得到对端ACK的”,“已经发送但还未收到对端ACK的”,“未发送但对端允许发送的”,“未发送且对端不允许发送”。“已经发送但还未收到对端ACK的”和“未发送但对端允许发送的”这两部分数据称之为发送窗口。
在这里插入图片描述
当收到接收方新的ACK对于发送窗口中后续字节的确认是,窗口滑动,滑动原理如下图。
在这里插入图片描述
当收到ACK=36时窗口滑动。2)对于TCP的接收方,在某一时刻在它的接收缓存内存在3种。“已接收”,“未接收准备接收”,“未接收并未准备接收”(由于ACK直接由TCP协议栈回复,默认无应用延迟,不存在“已接收未回复ACK”)。其中“未接收准备接收”称之为接收窗口。

发送窗口与接收窗口关系

TCP是双工的协议,会话的双方都可以同时接收、发送数据。TCP会话的双方都各自维护一个“发送窗口”和一个“接收窗口”。其中各自的“接收窗口”大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的“发送窗口”则要求取决于对端通告的“接收窗口”,要求相同。
在这里插入图片描述

滑动窗口实现面向流的可靠性

  1. 最基本的传输可靠性来源于“确认重传”机制。
  2. TCP的滑动窗口的可靠性也是建立在“确认重传”基础上的。
  3. 发送窗口只有收到对端对于本段发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
  4. 接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。

拥塞控制

TCP不仅可以可以控制端到端的数据传输,还可以对网络上的传输进行监控。这使得TCP非常强大智能,它会根据网络情况来调整自己的收发速度。网络顺畅时就可以发的快,拥塞时就发的相对慢一些。拥塞控制算法主要有四种:慢启动,拥塞避免,快速重传和快速恢复。

慢启动和阻塞避免

慢启动和拥塞避免算法必须被TCP发送端用来控制正在向网络输送的数据量。为了实现这些算法,必须向TCP每连接状态加入两个参量。拥塞窗口(cwnd)是对发送端收到确认(ACK)之前能向网络传送的最大数据量的一个发送端限制,接收端通知窗口(rwnd)是对未完成数据量的接收端限制。cwnd和rwnd的最小值决定了数据传送。另一个状态参量,慢启动阀值(ssthresh),被用来确定是用慢启动还是用拥塞避免算法来控制数据传送。在不清楚环境的情况下向网络传送数据,要求TCP缓慢地探测网络以确定可用流量,避免突然传送大量数据而使网络拥塞。在开始慢启动时cwnd为1,每收到一个用于确认新数据的ACK至多增加SMSS(SENDER MAXIMUM SEGMENT SIZE)字节。慢启动算法在cwnd<ssthresh时使用。当cwnd和ssthresh相等时,发送端既可以使用慢启动也可以使用拥塞避免。 当拥塞发生时,ssthresh被设置为当前窗口大小的一半(cwnd和接收方通告窗口大小的最小值,但最少为2个报文段)。如果是超时重传,cwnd被设置为1个报文段(这就是慢启动,其实慢启动也不慢,它是指数性增长,只是它的起始比较低)当达到ssthresh时,进入拥塞避免算法(拥塞避免是线性增长)。
在这里插入图片描述

在该图中我们可以清楚的看到,ssthresh最初等于8 MSS 。 拥塞窗口在慢启动期间以指数方式快速上升并在第三次传输时达到ssthresh。 然后,拥塞窗口线性地爬升,直到发生丢失(超时),就在发送7之后。当发生丢失时,拥塞窗口是12 MSS 。 然后将ssthresh设置为6 MSS并且将cwnd设置为1,并且该过程继续。

慢启动指数上升的原因:每次收到一个对新报文段段确认时(不算重传),就使发送方的拥塞窗口加1,所以收到n个报文段时,拥塞窗口变为2n,并发送2n的报文段,因此实现指数上升。

拥塞避免算法:每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1MSS字节。

快速重传和快速恢复

当接收端收到一个顺序混乱的数据,它应该立刻回复一个重复的ACK。这个ACK的目的是通知发送端收到了一个顺序紊乱的数据段,以及期望的序列号。发送端收到这个重复的ACK可能有多种原因,可能丢失或者是网络对数据重新排序等。在收到三个重复ACK之后(包含第一次收到的一共四个同样的ACK),TCP不等重传定时器超时就重传看起来已经丢失(可能数据绕路并没有丢失)的数据段。因为这个在网络上并没有超时重传那么恶劣,所以不会进入慢启动,而进入快速恢复。快速恢复首先会把ssthresh减半(一般还会四舍五入到数据段的倍数),然后cwnd=ssthresh+收到重复ACK报文段累计的大小(即3个报文段的长度)。

在这里插入图片描述

这个图上我们可以看出,在三次重复ACK后cwnd并没有进入到慢启动,而是进入到了快速重传。在第二段超时重传时,进入到了慢启动cwnd置1。

总结:快速重传机制是为了防止发送段误以为是因为网络拥塞而造成的失序而错误的启动慢启动造成传输效率的降低,快速重传算法首先要求接受端要立即发送确认,当受到3个冗余ACK时,立即进行重传,然后并不使用慢启动,而是使用快速恢复算法,将ssthresh = cwbd / 2,cwnd = ssthresh + 3 * MSS,并开始执行拥塞避免算法。

发送方窗口大小

发送方窗口取决于接受窗口和拥塞窗口中的较小值。
发送方窗口的上限值 = Min[rwnd, cwnd]

其中rwnd是接受窗口,cwnd是拥塞窗口。

发布了18 篇原创文章 · 获赞 0 · 访问量 290

猜你喜欢

转载自blog.csdn.net/weixin_42162340/article/details/103375399