TCP可靠性的的保证有这几种方式:数据包校验、序列号与应答机制、重传机制、滑动窗口控制、流量控制、拥塞控制。
重传机制
如果数据包或确认应答在传输过程中丢失了,那就会用重传机制来解决。重传机制的话首先是超时重传,就是当时间到了RTO后,还没接收到相应的消息,那就重传,但是这种方法存在的问题是周期相对来说比较长。还有一种是快速重传,假如就是客户端连续发了1234四个消息给服务端,然后服务端没收到序列号为2的包,那么这个时候服务端收到的几个消息都要回应的确认号为2,表示没接收到序列号为2的消息,那么客户端就重发序列号为2的消息,服务端收到2后,就直接发序列号为5的回应,因为之前的3和4已经接收到了嘛,但是这种方法客户端其实并不知道是丢了2而已,还是丢了234,要重传几个,要解决这种方法就是使用SACK,就是在TCP头部选项字段中加一个SACK的东西,它可以将缓存的数据发送给发送方,这个发送方就可以知道哪些数据收到了,哪些数据没收到,这样就可以只重传丢失的数据。
滑动窗口
如果没有滑动窗口的话,就是每次发送数据包,都要进行一次确认应答,当上一个数据包收到了应答了,再发送下一个,但是这样效率是比较低的。所以引入了窗口这个概念,窗口大小就是无需等待确认应答,而可以继续发送数据的最大值。TCP报文里面有个window字段,就是窗口大小,这个字段是接收方告诉发送方自己还有多少缓存区可以接收数据。而这个窗口大小一般是由接收方的接收能力来决定的。我以接收方为例,就是大概可以划分为3个部分,一是已成功接收并确认的数据大小,也就是等待应用程序读取的部分、二是未收到数据但可以接收的数据大小,也就是接收方窗口的大小、三是未收到数据且不可以被接收的数据大小。 (发送方的话有已发送并收到ACK确认的数据、已发送但未收到ACK确认的数据、未发送但总大小在接收方处理范围内、未发送但总大小超过接收方处理范围。)
流量控制
TCP是利用滑动窗口来实现流量控制的,可以让发送方根据接收方的实际接收能力,然后去影响发送方的发送速率。主要就是接收方新到内存缓冲区的字节数如果一直大于应用程序处理的字节数,那么我们的缓冲区迟早会满,这个时候就得一直把剩余的可容纳的缓冲区大小发送给发送方,发送方就根据这个大小去调整自己的发送速率。然后当这个窗口值为0时,发送端就会开启一个持续计数器,每隔一小段时间询问一下接收方的窗口大小。
拥塞控制
额。就是当网络出现拥堵时,如果再无限制的发送大量数据包,那么会导致更多的数据包时延啊、丢失啊什么的,这时TCP就会重传,一重传就导致网络的负担更重,所以就要考虑网络中的情况。然后呢,拥塞控制是相对于发送方来说的,如果不考虑拥塞控制的话,发送方的窗口大小是约等于接收方的窗口大小的,但是有了拥塞控制的话,发送方的窗口大小就是接收方的窗口大小和拥塞窗口中的较小值。然后拥塞控制主要是四个算法,慢启动、拥塞避免、拥塞发生、快速恢复。慢启动的话就是每接收一个ACK应答就加一,所以就是1、2、4、8这样。这样达到一个慢启动门限的阈值,就会来到拥塞避免,就是每收到一个ACK,就加加拥塞窗口分之一,这样慢慢加后,终会发送拥塞,拥塞发生的话,就会发生数据包重传,重传机制主要有两种,为超时重传和快速重传。当发生超时重传时,慢启动门限就会变成拥塞窗口的二分之一,拥塞窗口变为1。但这样太激进了,之前窗口大小那么大,现在就变成了1,反映就太强烈了,会造成网络卡顿。所以有更好的快速重传,就是拥塞窗口设置为一半,慢启动门限设置现在这个拥塞窗口大小,然后进入快速恢复算法,就是在拥塞窗口在一半的基础上再加上3,这样的话就不至于变化太大,窗口大小仍保持在一个相对高的值。
