TCP 发送一个数据,如果需要收到确认应答,才会发送下一个数据。这样的话就会有个缺点:效率会比较低。
“用一个比喻,我们在微信上聊天,你打完一句话,我回复一句之后,你才能打下一句。假如我没有及时回复呢?你是把话憋着不说吗?然后傻傻等到我回复之后再接着发下一句?”
为了解决这个问题,TCP 引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。
TCP 头部有个字段叫 win,也即那个 16 位的窗口大小,它告诉对方本端的 TCP 接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
“通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是 win。”
TCP 滑动窗口分为两种: 发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:
已发送且已收到 ACK 确认
已发送但未收到 ACK 确认
未发送但可以发送
未发送也不可以发送
深蓝色框里就是发送窗口。
SND.WND: 表示发送窗口的大小, 上图虚线框的格子数是 10个,即发送窗口大小是 10。
SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。
接收方的滑动窗口包含三大部分,如下:
已成功接收并确认
未收到数据但可以接收
未收到数据并不可以接收的数据
蓝色框内,就是接收窗口。
REV.WND: 表示接收窗口的大小, 上图虚线框的格子就是 9 个。
REV.NXT: 下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。