理解滑动窗口,先了解下面四个小知识
  • TCP使用两个缓存和两个窗口控制字节流的传输过程。发送方有一个发送缓存,用了存储进程准备发送的数据。接收方有一个接收缓存,用来存储接收成功的数据,等待接收方应用程序读取。接收方通过接收缓存的空余空间,计算出接收窗口的大小,并且会通过应答报文告知发送方。发送方也有一个发送窗口,只要这个窗口不为0,发送方就可以发送数据。
  • TCP不可能为对每个字节都进行确认,而是采用累积确认的方式对发送的数据进行确认。如果发送方收到ACK报文中的确认序号为:522,则表示编号为521号之前的数据都已经被成功接收,下面开始接收编号522之后的数据了。
  • 每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动,将新的数据包含到窗口中准备发送
  • 每个窗口用三个指针表示,第一个指向窗口的第一个字节,第二个指向窗口中马上要发送的字节,第三个指向窗口的最后一个字节。
传输字节的状态分类
  • 已经成功发送的
  • 已经发送,还没有收到确认报文的
  • 准备发送的数据
  • 还没准备发送的数据。
滑动窗口移动样例(参考博客:滑动窗口介绍

TCP建立连接的初始,B会告诉A自己的接收窗口大小,比如为‘20’:
字节31-50为发送窗口
TCP滑动窗口协议_网络知识

A发送11个字节后,发送窗口位置不变,B接收到了乱序的数据分组:
TCP滑动窗口协议_tcp_02

只有当A成功发送了数据,即发送的数据得到了B的确认之后,才会移动滑动窗口离开已发送的数据;同时B则确认连续的数据分组,对于乱序的分组则先接收下来,避免网络重复传递。
如果,中途那些乱序的数剧在重传定时器所规定的时间内都没有收到ACK报文段的话,A就会重传报文,至于,重传的机制有:
- 选择重传
- 回退N步
这两个重传机制,我们将在后续的博客中介绍。TCP报文重传的次数也根据系统设置的不同而有区分,有些系统,一个报文只会被重传3次,如果重传三次后还未收到该报文的确认,那么就不再尝试重传,直接reset重置该TCP连接。但有些要求很高的业务应用系统,则会不断的重传被丢弃的报文,以尽最大可能保证业务数据的正常交互。

数据报丢失的原因
  • 交换机或路由器过载使TCP包或确认包丢失;
  • 接收端对TCP包的确认速度慢,致使发送端超时重发;
  • 接收端缓存溢出;
  • TCP数据包在传输过程中丢失或损坏;
  • 发送端与接收端之间的距离太远或传输速度太慢
总结

TCP协议使用以字节为单位的滑动窗口的协议来控制字节流的发送、接收、确认和重传过程,另外还可以用它来进行流量控制和拥塞控制。其实“滑动”的含义是指TCP进程在发送端有序的从发送缓存中提取数据并且发送给接收端,而接收端又通过接收缓存来间接控制发送端一次可以发送的数据量的大小。