必须掌握的TCP全家桶系列详细解读:流量控制、三次握手、四次挥手及拥塞控制算法

目录

开篇

一、TCP如何保证可靠传输?

1、滑动窗口

2、超时重传和快速重传

3、选择确认

二、TCP的流量控制

三、TCP三次握手

四、TCP四次挥手

五、TCP的拥塞控制

1、慢启动和拥塞避免

2、快速恢复

结语


开篇

今天下午广州下着小雨,屋外“沙沙”的雨声很治愈,心情舒畅,想起诗句“小桥流水人家”,已经好久没接触古诗词啦,现在想想以前学的古典文学,有种久违的优美。驾一叶扁舟于江中,朦胧细雨,惠风和畅。以上这句话是我自己编的๑乛◡乛๑,以后有时间就读读古诗文学,感觉挺不错的*^_^*

后来雨下得越来越大,还伴有“轰隆”的雷声,这时我才缓过神来,发现写着写着跑题了哈,然后赶紧进入正题,外面的风景虽好,自己的遐想也好,今天任务还没完成呢!今天想要写的学习总结是TCP非常关键的知识,正如我起的题目“必须掌握的TCP全家桶系列”,后面会发现这一系列下来,联系都挺密切的,感兴趣的伙伴可以往前找我写的,比如《运输层UDP报文、TCP协议内容 一篇精华总结!》。

一、TCP如何保证可靠传输?

1、滑动窗口

“滑动窗口”这个概念现在应该不陌生了,在数据链路层的时候就出现过这个概念,是一个很形象的名字,协议的工作过程中,发送窗口不断向前滑动。可以瞧瞧这篇《计算机网络学习:封装成帧、差错检测和可靠传输》。

当然,这里讲的是运输层TCP协议的可靠传输,原理相似,具体有一点差别。

TCP协议是面向字节的,所以滑动窗口也是以字节为单位。同样采用累积确认的方式,对按序接收到的数据进行确认,确认号表示下一个期望收到数据字节的第一个编号

另外,因为TCP提供了全双工的通信,不需要双方特地发送确认报文,发送数据的时候捎带确认信息,采用了延迟确认的机制,这样提高了TCP的传输效率。

一图胜万字,就是这样。

上图表示窗口大小为400字节,发送的数据不能超过窗口大小只有发送的数据被确认后,窗口才向前滑动。比如初始化序号为1,第一次发送1-401字节这段数据,然后收到1-201的确认,窗口向前滑动至701因为301-401未收到确认,现在能使用的窗口只有200字节,也就是说最多只能再发送200字节的数据。

还有一个重要的地方,发送窗口只是发送缓存的一部分,在实际TCP应用程序中,缓存空间和序号空间是有限的,这部分缓存类似循环队列的存在可以循环使用

2、超时重传和快速重传

在数据链路层中也有超时重传的机制,设置的超时阈值相对简单,因为数据链路层的往返时间比较固定。而TCP中的超时重传机制,就显得比较复杂了,TCP工作的环境十分复杂,网络拥塞情况不确定,这对于设定超时阈值时间就很困难。往返时间PTT的计算有着许多算法,比如自适应算法、Karn算法,目的都是尽可能正确的计算报文的往返时间,这样才能保证可靠传输,没有差错

尽管这样,在实际中如果一个超时时间比较长,这样效率低下,不利于传输数据。因此,快速重传可以更好的保证TCP的可靠传输并提高效率。

快速重传的工作过程在下图可以很直观地看到。

发送方发送了M1-M6报文,期间M3报文丢失,收到M4时候发现序号不对,后面到达的M5-M6都暂且存放于缓存,这时根据快速重传算法规定,对按序到达的最后的数据的序号进行三次重复确认,表示需要重传下一个序号的数据。

这样一来,可以更快的告知发送方需要重传的数据,保证了效率。

3、选择确认

上面提到,TCP采用累积确认的方式,同时会将未按序到达的数据接收存放于缓存,但是这部分已经接收的字节数据并未收到确认,会被误认为超时要求发送方重传。显然,这是多余无意义的。

因此,TCP启用了选择确认的功能。这样接收方可以通知发送到已接收的未按序字节块,发送方就不用再次重传这些数据。这与选择重传协议(SR)很类似,不过它是更改为逐一确认方式。

TCP依然使用累计确认,这时一个确认号不够用,所以需要不连续字节块的左右边界来标识,这部分信息存放在TCP首部的可变长选项

二、TCP的流量控制

所谓流量控制,就是接收方会根据自身情况来告知发送方自己的缓存容量避免发送数据太快来不及接收,造成数据丢失或者缓存溢出

TCP流量控制更像一种速率匹配服务,匹配发送速率和接收速率。流量控制的方法实质是控制发送窗口的大小。接收方会在TCP首部写入对发送方窗口大小的设置要求,由接收方控制发送方的形式

上图中,接收方进行了三次流量控制。最后一次告知发送方不能发送数据,因为接受缓存满了。这样一来,如果发送方还有数据,怎么办呀?

这时,为了防止这种死锁的状态,发送方会周期性的发送一个窗口探测报文,强制接收方告知接收窗口大小

三、TCP三次握手

TCP建立连接的三次握手过程可以说是很经典的问题。

那为何是三次握手?

TCP是面向连接的协议,建立连接需要解决这三个问题。

  1. 使双方的任一方知道对方的存在;
  2. 双方协商好初始化参数(MSS、窗口大小等);
  3. 对运输实体资源(缓存大小、状态变量等)进行分配。

TCP连接采用C/S架构。过程如图(来源:百度百科)

详细过程:

第一次握手,客户端向服务器发送连接请求报文,标识SYN=1(表示请求报文),seq=x(表示序号),确认客户端的发送能力和服务器是否有接收能力。

第二次握手,服务器接受请求,进行确认,SYN=1,ACK=1(表示确认),确认号ack=x+1,数据序号seq=y,确认客户端的接收能力和服务器是否有发送能力。

第三次握手,客户端响应服务器的接受连接确认,进行确认收到,SYN=0,ACK=1,ack=y+1,seq=x+1,确认各方的接收能力和发送能力。

回头一看,似乎第三个报文客户端的确认有点多余,其实不然。第三个报文的确认,防止了已失效的连接请求报文段突然传送到服务器,造成错误的问题。

为何会如此一说?

假设一种情况,客户端发送的请求报文并未丢失而是延误时间很长,直到这次连接释放后才传到服务器,显然这是已经失效的报文了。但是,服务器会误认为客户端再次请求,然后发送请求的确认,我们知道这时客户端并不会理睬它,因为它没有发送连接请求。后果就是服务器一直等待客户端发送数据,许多资源因此白白浪费。

如果只有两次握手,这个例子很好理解:

朋友:快借我点钱,我的账号是123XXXXXXXX

你:好的, 我转到你的帐号了,收到了吗

朋友再无应答……

这时候,你的内心???钱会不会没了……

总结下来,两次握手所带来的问题:不可靠,还会造成网络资源的浪费。

因此,第三个报文的确认是必要的,三次握手才能保证双方建立正确的连接,可以互相通信

四、TCP四次挥手

TCP释放连接,经过了四次挥手的过程,也可以看作两个两次握手。

看图说话(来源:百度百科)

详细过程:

  1. 客户端进程发送连接释放报文,并且停止发送数据。TCP报文首部,FIN=1(表示终止),seq=u。TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器确认连接释放报文报文ACK=1,ack=u+1,seq=v,此时,服务端就进入了CLOSE-WAIT(被动关闭等待)状态。客户端向服务器的方向就释放了,处于半关闭状态,客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然可以接受。这个状态还要持续CLOSE-WAIT状态的时间。客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2状态,等待服务器发送连接释放报文。
  3. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  4. 客户端收到服务器的连接释放报文后,必须发出确认ACK=1,ack=w+1,seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL的时间后,才进入CLOSED状态。服务器收到了客户端发出的确认,立即进入CLOSED状态。可以看到,服务器结束TCP连接的时间要比客户端早一些。

五、TCP的拥塞控制

TCP的拥塞控制和前面的流量控制联系比较密切,流量控制维护一个接收窗口(rwnd)来限制发送窗口的大小,实际上TCP还维持了一个拥塞窗口(cwnd),窗口大小取决于网络拥塞程度。

所以,TCP发送方在发送报文时,不仅要根据接收方的接收能力,还要全局考虑网络的拥塞程度,调整发送窗口大小。满足公式发送窗口大小=Min(rwnd,cwnd).

TCP对网络拥塞的判断依据:超时或者收到三个重复确认

拥塞控制算法:慢启动、拥塞避免、快速恢复

1、慢启动和拥塞避免

TCP定义了一个慢启动门限ssthresh,有以下过程:

  1. 当cwnd(拥塞窗口)< ssthresh,使用慢启动算法。即每确认一个新报文,cwnd加1。比如初始化cwnd=1,发送第一个报文M0确认后,cwnd=2;接着可以发送M1、M2,确认后cwnd=4,以此类推,为指数增长。
  2. 当cwnd > ssthresh ,使用拥塞避免算法。即每轮确认才增加一个单位拥塞窗口,呈线性增长。当网络出现拥塞,ssthresh降为原来的一半,拥塞窗口变为1,重新轮回。拥塞避免实际是使网络不容易出现拥塞
  3. 当cwnd = ssthresh ,既能使用慢启动算法,也可以使用拥塞避免算法

2、快速恢复

因为拥塞的依据包含超时和三个重复确认,其实这两种情况的拥塞程度是不同的,如果突然将拥塞窗口设置为1,可能造成更剧烈的拥塞。

快速恢复则是快速重传的配套算法。

算法的不同之处在于:当收到的是三个重复确认时候,拥塞窗口不再设置为1,而是设置为新的ssthresh值,然后再使用拥塞避免算法,线性增长

所以,对于不同情况的拥塞,采用不同的算法更好地保证网络质量。

结语

写到这里,外面的雨还是下得很大,但是影响不大。到现在,计算机网络运输层的部分基本学习总结完成了,我觉得这一篇是最重要的,TCP的核心思想都在这里,如果掌握了这部分对于网络的传输基本都能理解,这篇起名为“必须掌握的TCP全家桶系列详细解读”,很明显它就很重要,是干货,建议阅读收藏哦!

与本篇的知识相关的可以查看:计算机网络学习:封装成帧 、差错检测和可靠传输运输层UDP报文、TCP协议内容 一篇精华总结!

如果觉得不错欢迎“一键三连”哦,点赞收藏关注,评论提问建议,欢迎交流学习!一起加油进步! 


我的CSDN博客:https://csdn-czh.blog.csdn.net/article/details/116356740

相关推荐
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页