1、滑动窗口
TCP的滑动窗口是以字节为单位的。为了便于说明,字节编号取的很小。先假定A收到B发来的确认报文字段,其中窗口是20字节,而确认号是31字节。(表明B期望接收到的下一个序号是31,序号30之前的数据已经收到了)。如图下图所示:
A收到B的确认号是31,这表示B已经成功接受前面30个字节的数据,即发送窗口后沿部分。并告诉A发送窗口大小为20个字节。
发送窗口的含义是:A接下来可以把窗口内的数据都发送出去,而且在A未收到B的确认前,A将根据超时重传机制,重发窗口内的数据(暂存未收到确认的数据,并设置计时器)。
注意:A的发送窗口大小不能超过B的接受窗口的大小。
2、窗口后沿、前沿
发送窗口的位置,右前沿和后沿共同确定。
例子中:窗口大小为:31 - 50 ,供20个字节。
2.1、后沿位置有两种情况:
- 后沿不动:
表示一直没收到确认信息。
- 后沿向前移动
表示收到了发送窗口内的连续确认信息。
注意:后沿窗口不可能向后移动,这是因为不可能撤销已经确认的信息
2.2、前沿位置有可能也有两种情况:
- 向前移动
正常收到确认信息,通知的窗口大小不变,或者变大。
比如:收到2个字节的确认,即使通知的窗口大小不变,前沿也会向前移动2个字节。
- 不动
没有收到确认消息,对方通知的窗口大小也不变;
收到确认消息,但是对方通知的窗口变小
例如: 收到2个字节的确认,通知窗口大小减少2个字节。这种情况下窗口大小刚好不变。
- 向后收缩
例如:收到2个字节的确认,但是对方的通知窗口大小减少3个字节,导致前沿位置向后收缩。
注意:TCP标准强烈不赞成这样做
3、滑动窗口原理
3.1、发送方
现在假定A发送了序号为31-41的数据,如上图所示,一个发送窗口的状态需要三个指针:P1,P2,P3;指针都指向字节的序号。
小于P1的是已发送并收到确认的部分,大于P3的是不允许发送部分。
P3 - P1 = A发送窗口的大小(又称为通知窗口);
P3 - P2 = 允许发送但尚未收到的字节数(又称为可用窗口或有效窗口),表示A的可用窗口;
P2 - P1 = 已发送,未收到确认的字节数;
3.2、接收方
如果B收到了序号为32,33的两个数据,所以,A的数据没有有顺到达,序号为31的数据没有收到。B发送的确认报文段中,确认号仍然是31。
假如B收到了31序号的数据,那么B将31,32,33三个字节的数据交付上层应用程序。并从接收缓存中删除这些数据,并在返回报文中将确认号修改为34(下次想收到的第一个字节的序号)。
当A收到确认报文后,将发送窗口向前移动3个字节,但指针P2不动。A的可用窗口变大了。
如下图所示,B的接收窗口前沿和A的发送窗口前沿都向前滑动了3个字节,并且B还收到了序号为37,38,40的字节。但因为不是连续的字节,并且起始序号不是34,所以B在接收缓存中缓存这部分数据。
A继续发送完序号42-53的数据后,P2移动到和P3重合。这是A的可用窗口变为0,停止发送数据。
异常情况:A成功发送42-53的数据,B也收到了这些数据,并且B也给出了确认号为53的数据。但是因为B的确认信息,一直滞留在网络中。当A等待的时间,超过超时重传机制设置的定时器时间时,A将重传42-53的数据。直到收到B的确认号为止。
3.3、注意
B可以返回连续接收到的最大序号+1,作为确认号回复给A。
例如:B成功接收到34-40序号的数据(上次B缓存了37,38,40,然后B又收到了34,35,36序号的字节的报文),B会给出去确认号为41的确认报文。A收到B确认号为41的报文后,A的发送窗口前沿将向前移动7个字节,即P2不动,待在54的地方,P3移动到61的地方。同理,P1移动到41的位置(即B发送的确认号)。
从上面看得出来,A的可用窗口的大小表示A可以发送的字节数。B的P1指针是B返回的最新的确认号。
4、TCP缓存
发送缓存和接收缓存的大小都有限制,并可以重复使用。
4.1、发送缓存
从上图可以看出,发送缓存和发送窗口的后沿重合,并且被确认的数据应该从发送缓存中移除。
一般的关系是:
已发送 < 发送窗口 < 发送缓存
发送缓存用来存放:
-
- 发送应用程序传递给发送方TCP准备发送的数据;
- TCP已发送,但是没有收到的确认的数据。
4.2、接收缓存
接收缓存用来存放:
-
- 按序到达,还未被接收应用程序读取的数据;
- 未按序到达的数据。
接收窗口的大小收到接收应用程序读取数据的速度影响。如果接收应用程序来不得读取收到的数据,则接收缓存最终会被填满,而使接收窗口变为0;反之,接收应用程序能够及时从接收缓存中读取收到数据,接收窗口就会变大,但最大也不能超过接收缓存的大小。所以,接收应用程序读取数据的速度越快,接收窗口会越大。但是最大不能超过接收缓存的大小。