前几篇已经说明了TCP的复杂性,因为TCP既要保证可靠性, 同时又要尽可能提高性能。
保证可靠性的机制,有序列号(按序到达)、确认应答、校验和(华为网络基础 | IP包校验和算法实例抓包验证、华为网络基础 | TCP校验和算法实例抓包验证及华为网络基础 | TCP校验和错误原因及再次实例抓包验证)、连接管理(华为网络基础 | TCP连接管理机制及华为网络基础 | TCP断开连接管理机制)和超时重传机制,今天继续讲解流量控制和拥塞控制。
一、流量控制
接收端处理数据的速度是有限的,如果发送端发的太快, 导致接收端的缓冲区被填满, 这个时候如果发送端继续发送, 就会造成丢包, 进而引起丢包重传等一系列连锁反应。
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度,这个机制就叫做流量控制(Flow Control)
接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK通知发送端; 窗口大小越大, 说明网络的吞吐量越高; 接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端; 发送端接受到这个窗口大小的通知之后, 就会减慢自己的发送速度; 如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 让接收端把窗口大小再告诉发送端。
那么接收端如何把窗口大小告诉发送端呢?
我们的TCP首部中, 有一个16位窗口大小字段, 就存放了窗口大小的信息; 16位数字最大表示65536, 那么TCP窗口最大就是65536字节么?
实际上, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是窗口字段的值左移 M 位(左移一位相当于乘以2)。
二、拥塞控制
虽然TCP有了滑动窗口这个大杀器, 能够高效可靠地发送大量数据,但是如果在刚开始就发送大量的数据, 仍然可能引发一些问题,因为网络上有很多计算机, 可能当前的网络状态已经比较拥堵,在不清楚当前网络状态的情况下, 贸然发送大量数据, 很有可能雪上加霜。
因此, TCP引入慢启动机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态以后, 再决定按照多大的速度传输数据。
在此引入一个概念拥塞窗口:
1、发送开始的时候, 定义拥塞窗口大小为1;
2、每次收到一个ACK应答, 拥塞窗口加1;
3、每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口。
像上面这样的拥塞窗口增长速度, 是指数级别的,“慢启动” 只是指初使的时候慢, 但是增长速度非常快。
为了不增长得那么快, 此处引入一个名词叫做慢启动的阈值, 当拥塞窗口的大小超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长。
1、当TCP开始启动的时候, 慢启动阈值等于窗口最大值;
2、在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1。
少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为是网络拥塞; 当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降。
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案。
关于网络基础知识——TCP协议保证可靠性的机制,我们差不多讲解完成,后续的吸收还得读者自行花时间解决。接下来我们将讲解提高性能的机制:滑动窗口、快速重传、延迟应答以及捎带应答等。