1.流量控制概念
接收端处理数据的速度是有限的,如果发送方的速度太快,就会把缓冲区打满。这个时候如果继续发送数据,就会导致丢包等一系列连锁反应。
所以 TCP 支持根据接收端能力来决定发送端的发送速度。这个机制叫做流控制。
2.流控制
它的具体操作是,接收端主机向发送端主机通知自己可以接收数据的大小,于是发送端会发送不超过这个限度的数据。该大小限度就被称作窗口大小。窗口大小的值就是由接收端主机决定的。
3.窗口大小
在 TCP 报文头部,有一个 16 比特的窗口字段,用来表示接受方的缓冲区大小,接收主机将自己可以接收的缓冲区大小放入这个字段中通知给发送端。这个字段的值越大,说明网络的吞吐量越高。不过,接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之被设置为一个更小的值通知给发送端,从而控制数据发送量。也就是说,发送端主机会根据接收端主机的指示,对发送数据的量进行控制。
TCP 的流量控制由连接的每一端通过声明的窗口大小来提供 。窗口大小为字节数 ,起始于确认序号字段指明的值,这个值是接收端期望接收的字节。窗口大小是一个 16 bit 字段,因而窗口大小最大为 65535 字节。
4.窗口扩大因子 M
TCP 基于通告窗口大小的机制,运行发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。TCP 传输速率和窗口大小成正相关,在某些情况下,提高窗口大小能够提高传输速率。
但 TCP 窗口大小只有 16bit,最大表示 65535 字节,对当前千兆接口已经是标配,在数据中心对服务器上开始部署 10G 接口的现实情况下,65535 字节的窗口显然是不够的。
常见对 TCP 选项有 7 种,其中 kind=3 是窗口扩大因子选项。TCP 连接初始化时,通信双方使用该选项来协商接收通过的窗口扩大因子。假设 TCP 头部中的通告窗口大小为 N,窗口扩大因子(位移数)是 M,那么 TCP 报文段的实际接收通告窗口大小为:N * (2 *M)。M 的取值范围为 0 ~ 14。这样的话,通告窗口最大约为 1GB,能够满足大部分应用的需求。
5.抓包查看窗口信息
下图为 WireShark 抓取的一个 tcp 包的 tcp 包头结构
tcp包的tcp包头结构
从中我们可以看到,窗口大小为 16448,但是计算之后窗口大小为:65792,因为扩大因子为 4,65792=4*16448。
6.流量控制演示
流量控制演示
主机 A 发送 1000bit 的数据给主机 B,这时候主机 B 告诉主机 A,我的窗口大小为 3000,你可以多发点过来,
当主机 B 收到从 3001 号开始的数据段后其缓冲区挤满。
不得不告诉主机 A 暂时停止发送数据,之后窗口收到更新通知后才得以继续进行。
如果这个通知在途中丢失了,可能导致无法继续通信。
所以发送方会时不时发送一个窗口探测的数据段。
此数据端仅含一个字节来获取最新的窗口大小。
当主机 B 处理完之后又会告诉主机 A,我还剩 2000 的空间。你可以继续发送了。