一.窗口
在TCP中由于要保证可靠性,所以每发送一条数据后,都需要接收方返回一条应答报文,要是我们每发送一条数据,发送方就等待接收应答报文,收到之后再去发送下一条数据,这样我们就会花费大量的时间在等待应答报文上,效率是很低下的
所以TCP中有了窗口的概念,TCP在发送数据的时候会一次性发送一组数据,发送这一组数据的过程中不用等待ACK(应答报文),就直接往接收方发,而窗口大小就是我们发送这一组数据的大小,如上图,当窗口大小为4000个字节(四个段)时,我们在发送序号为1-4000的信息就直接发送给接收方即可,不需要等待接收方返回ACK(应答报文),在发送好一组数据以后,我们再等待ACK(应答报文),相当于使用一份等待时间,等待四个ACK(应答报文)
窗口能不能无限大呢
当我们的窗口越大,此时批量发送的数据就越多,效率就越高,那我们的窗口能不能及其的大呢,这样效率不就非常高了吗?答案是不行,因为窗口要是过于大,批量发送的数据就会很多,就不知道要到什么时候才去等待ACK(应答报文)了,就相当于完全不必等ACK(应答报文),此时就和不可靠传输差不多了,而TCP的特点就是可靠传输,并且如果窗口过于大,批量发送的数据过于多,接收方能不能处理得过来,中间的网络设备能不能承受住,都是未知数
二.滑动窗口
滑动窗口,是一个形象的比喻,实际上就是批量发送数据,这样可以缩短等待时间,提高一定的效率(缩短不代表没有,仍然需要一定的时间等待ACK(应答报文),所以传输效率不会比UDP高)
如上图,我们在发送一组数据后,等待ACK(应答报文)时,我们需要等待4个段的应答报文都获得了才去发送下一段数据吗,很显然,不需要,由于ACK(应答报文)的发送是有顺序的,所以我们肯定会先接收到当前组中,第一段的ACK(应答报文),当我们收到第一段的ACK(应答报文)后便可以发送下一段数据了,这样我们就保证了一直等待的都是4个段的ACK(应答报文),一段一段的向后推进,就像一个滑动窗口一样。
在滑动窗口中出现丢包应该怎么办?
1.ACK(应答报文)丢包
ACK(应答报文)丢包即使不做任何处理也是正确的,如上图,当1-1000序号的数据发送后,接收方返回的1001的确认序号( ACK(应答报文))出现了丢失,但后面1001-2000序号的数据发送后,接收方返回的2001的确认序号( ACK(应答报文))没有出现丢失,而2001的确认序号就表名在2001之前的数据都已经成功接收,其中就包括了1-1000的数据,所以即使 ACK(应答报文)出现了丢失后面的 ACK(应答报文)也能确认之前的数据被成功接收
所以在滑动窗口中 ACK(应答报文)丢包即使不做任何处理也是正确的
2.传输的数据丢包
如上图,在滑动窗口批量传输数据时,1001-2000这段数据出现了丢包,此时接收方就没有收到1001-2000这段数据,所以接收方之后返回的确认序号( ACK(应答报文))都是1001,就像是提醒发送端“我想要的是1001这个数据”一样
当发送端连续收到多次“1001”这样的应答,就会将对应的1001-2000的数据重新发送
此时接收端收到了1001后,再次返回的确认序号( ACK(应答报文))就是7001了,因为2001-7000的数据接收端之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中
这种机制叫做“高速重发控制”,也叫“快重传”
流量控制(滑动窗口的补充)
我们知道,滑动窗口越大,批量传输的数据越多,传输效率越高,但是窗口也不能无限大,窗口要是太大了,就有可能使接收方处理不过来,或者使传输的中间链路处理不过来,这样就会出现丢包,就得重传了,反而还影响了效率
流量控制就是给滑动窗口“踩踩刹车”,避免窗口太大,导致接收方处理不过来
流量控制就是根据接收方的处理能力来限制发送方的发送速度(窗口大小)
那我们如何衡量接收方的处理能力呢?通过接收方的接收缓冲区剩余空间大小来进行衡量,
接收缓冲区剩余空间大小越大,说明接收方的处理能力越强,发送方的发送速度(窗口大小)就可以越大,反之亦然
发送方如何知道接收方的处理能力呢?接收方接收到数据后都会给发送方发送ACK(应答报文),所以我们将接收方的接收缓冲区剩余空间大小通过ACK(应答报文)反馈给发送方,作为发送方下一次发送数据窗口大小的依据
如上图,发送端发送了1-1000的数据,接收端返回的ACK(应答报文)不仅有确认序号1001,还有接收端接收缓冲区的剩余空间大小3000字节,发送端收到ACK(应答报文)以后,便知道了接收端接收缓冲区还有3000字节的剩余空间大小,于是发送了1001-4000共3000字节的数据给接收端,当接收端返回的接收缓冲区剩余空间大小为0时,发送端就会不停的发送一个无意义的数据作为探测信号,去获取接收端接收缓冲区剩余空间大小,当不为0时,便可以继续传输数据。
滑动窗口并不是TCP就一定涉及
如果通讯双方大规模的传输数据,那么肯定就是滑动窗口
如果通讯双方传输数据的规模比较少,这个时候就不会用滑动窗口了,依然按照之前的发一个数据就等待一个ACK(应答报文)的方式工作