由于TCP的复杂性,已经用多篇文章来介绍 TCP保证可靠性的机制了(有序列号(按序到达)、确认应答、校验和(华为网络基础 | IP包校验和算法实例抓包验证、华为网络基础 | TCP校验和算法实例抓包验证及华为网络基础 | TCP校验和错误原因及再次实例抓包验证)、连接管理(华为网络基础 | TCP连接管理机制及华为网络基础 | TCP断开连接管理机制)和超时重传机制)和流量控制及拥塞控制, TCP的可靠性机制已经介绍完了,今天继续介绍TCP尽可能提高性能的滑动窗口、快速重传机制。
一、滑动窗口
前面我们已经讨论了确认应答机制, 对每一个发送的数据段, 都要给一个ACK确认应答, 收到ACK后再发送下一个数据段。
这样做有一个比较大的缺点, 就是性能较差,尤其是数据往返时间较长的时候。 那么我们可不可以一次发送多个数据段呢?
例如下图所示:
窗口大小指的是无需等待确认应答就可以继续发送数据的最大值。上图的窗口大小就是4000个字节 (四个段)。
发送前四个段的时候, 不需要等待任何ACK, 直接发送,收到第一个ACK确认应答后, 窗口向后移动, 继续发送第五六七八段的数据……因为这个窗口不断向后滑动, 所以叫做滑动窗口。
操作系统内核为了维护这个滑动窗口, 需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有ACK确认应答过的数据, 才能从缓冲区删掉。
二、快速重传
如果出现了丢包, 那么该如何进行重传呢?
此时分两种情况讨论:
1、 数据包已经收到, 但确认应答ACK丢了
这种情况下, 部分ACK丢失并无大碍, 因为还可以通过后续的ACK来确认对方已经收到了哪些数据包。
2、数据包丢失
当某一段报文丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要的是 1001” 。
如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 - 2000 重新发送 ,这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了。
因为2001 - 7000接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中。
这种机制被称为“高速重发控制”(也叫 “快重传”)。