本文参考了一些优秀的书籍->图解TCP/IP,TCP协议卷一,小林coding,还有等等的知乎,百度.
小林coding 小林coding
知乎牛客的文章 : 万字长文 | 23 个问题 TCP 疑难杂症全解析_技术交流_牛客网
这篇文章是关于TCP的又一个重要机制-->滑动窗口,下面是这篇文章的思维导图:
目录
理解滑动窗口
为啥要引入滑动窗口呢??
窗口的实质
理解累计确认
如何理解窗口大小
滑动窗口机制下,如何处理丢包??
ACK丢包???
数据包丢失???
发送方窗口与接收方窗口
发送方窗口
程序中是如何划分为这4个部分的??
窗口是如何滑动的???
接收方窗口
程序中是如何划分为这3个部分的??
接收的窗口大小与发送的窗口大小是完全相等的么??
在没有引入窗口的概念之前,都是发送方发一个数据报,接收方返回一个ACK,发送方才可以发送下一个数据报,这样的缺点就是如果数据报往返时间较长的话,传输数据的效率低下.
所以我们引入了窗口,在没有接收到上次发送数据的ACK,还可以发送下一个数据报,可以通过后面的ACK来确认前面发送的数据报也称为累计确认.
举一个例子给朋友发微信
没有窗口的情况下(一发一应的形式) :我给朋友发微信,我只能一直等待它给我回复信息,这样我等待的时间不能做其他的事情只能等待---降低了通信效率
有窗口的情况下 : 我给朋友发微信,我一次把我想说的话全部给他发过去,然后我先做其他的事情,等到不忙了在看他有没有回复信息,这样我可以在等待的时间做其他的事情,大大的提高通信效率.
窗口是将等待ACK的时间重叠在一起,可以一次发送多条数据,就大大的提高性能.
窗口实际上是操作系统开辟的一块缓冲区, 发送方发送数据就会将数据存放在缓冲区里面,如果发送方收到接收方回应的确认应答,这个数据就会从缓冲区里面删除.
这里假设窗口大小为3,使用滑动窗口机制连续发送3条数据,但是前两条数据的ACK丢失,但是由于第三个ACK是3001没有丢失,那证明3001之前的数据都收到了,这就是累计确认.
窗口大小是指在不等待ACK的前提下,所能发送数据的最大值.
窗口大小是由接收方告诉发送方自己还有多少缓冲空间可以接收数据,以至于发送方根据接收方的处理能力控制窗口大小来发送数据,防止接收方处理不过来.
所以,窗口大小是由接收方窗口大小确定的.
发送方的窗口大小不能大于接收方的窗口大小,防止接收方不能正常的接收数据(处理不过来).
如果可用窗口大小为0,那证明发送方需要等待收到确认应答之后才能发送数据,否则不能发送数据.
这里假设窗口大小为3,使用滑动窗口机制连续发送3条数据,但是前两条数据的ACK丢失,但是由于第三个ACK是3001没有丢失,那证明3001之前的数据都收到了,这就是累计确认.
当某个报文段丢失,窗口大小又比较大的情况下,接收方在没有收到自己预期的序号,会对上一次收到的数据进行确认应答,如果接收方连续三次收到重复的确认应答,那么就需要发送方重传数据包,这样的机制也要做快速重传机制
在滑动窗口机制下,如果数据报(报文段)丢失,那就会触发快速重传机制.
接收窗口被划分为4个部分:
程序根据3个指针来进行划分的,分别是2个绝对指针,一个相对指针进行划分
当接收方返回4个确认应答,那么发送窗口就向右移动4个位置,同时窗口的每个部分都在同时变化.
这里注意如果发送方一下把数据全部发送,可用窗口大小就为0,那么就无法再次发送数据,需要等待接收方确认应答腾出窗口大小才能发送数据
接收窗口分为3个部分
通过2个指针来进行划分
可以认为是约等于的关系,把数据放到接收缓冲区里面还需要应用进程来进行读取,如果应用进程读取数据过快,接收缓冲区很快就空了,接收窗口很快就空出来,这时还要将新窗口的大小需要通过TCP的Windows字段告诉我们,这个传输过程存在时延迟,所以不是完全相等的.
这里还要注意接收方将数据放到接收缓冲区里面不是立即就能读取的,需要应用进程进行读取.