一 TCP的滑动窗口协议
TCP协议作为一个可靠的面向流的传输协议,其可靠性是由流量控制和滑动窗口协议保证。
为什么需要流量控制?因为如果发送方发送数据过快时,接收方可能来不及接收,导致数据的丢失。
二 滑动窗口协议-概念解释
1. “窗口”对应的是一段可以被发送者发送的字节序列,其连续的范围称之为“窗口”
2.“滑动”则是指这段“允许发送的范围”是可以随着发送的过程而变化的,方式就是按顺序“滑动”。
3.TCP协议的两端分别为发送者A和接收者B,由于是全双工协议,因此A和B应该分别维护着一个独立的发送缓冲区和接收缓冲区,由于对等性(A发B收和B发A收),以下均以A发送B接收的情况来举例。
4.发送窗口是发送缓存中的一部分,是可以被TCP协议发送的那部分,其实应用层需要发送的所有数据都被放进了发送者的发送缓冲区。
5.发送窗口中相关的有四个概念:
已发送并收到确认的数据(不再发送窗口和发送缓冲区之内)
已发送但未收到确认的数据(位于发送窗口之中)
允许发送但尚未发送的数据(位于发送窗口之中)
发送窗口外发送缓冲区内暂时不允许发送的数据
6.每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动,将新的数据包含到窗口中准备发送;
TCP建立连接的初始,B会告诉A自己的接收窗口大小,比如为20:
网上找一些图:
31-50就是滑动窗口
A发送11个字节后,发送窗口位置不变,B接收到了乱序的数据分组:
只有当A成功发送了数据,即发送的数据得到了B的确认之后,才会移动滑动窗口离开已发送的数据;
同时B则确认连续的数据分组,对于乱序的分组则先接收下来,避免网络重复传递
三 流量控制
流量控制方面主要有两个要点需要掌握。一是TCP利用滑动窗口实现流量控制的机制;二是如何考虑流量控制中的传输效率。
所谓流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送:
需要注意的是:
这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉A我的rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知,同时,B等待A发送数据的死锁状态。为了处理这种问题,TCP引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待。
四 拥塞控制
网络中的链路容量和交换结点中的缓存和处理机都有着工作的极限,当网络的需求超过它们的工作极限时,就出现了拥塞。拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。常用的方法就是:
·慢开始、拥塞控制
·快重传、快恢复
1.慢开始&拥塞控制(也叫拥塞避免)
一切的基础都是慢开始,算法思路是这样的:
(1)发送方维持一个叫做拥塞窗口cwnd(Congestion Window)的变量,该变量和接收窗口rwnd(Received Window)共同决定了发送者的发送窗口
(2)当主机开始发送数据时,避免一下子将大量字节注入到网络,造成或者增加拥塞,选择发送一个1字节的试探报文
(3)当收到第一个字节的数据的确认后,就发送2个字节的报文
(4)若再次收到2个字节的确认,则发送4个字节,依次递增2的指数级
(5)最后会达到一个提前预设的“慢开始门限”,比如24,即一次发送了24个分组,此时遵循下面的条件判定: 其中ssthresh是慢启动阈值
·cwnd < ssthresh, 继续使用慢开始算法
·cwnd > ssthresh,停止使用慢开始算法,改用拥塞避免算法
·cwnd = ssthresh,既可以使用慢开始算法,也可以使用拥塞避免算法
(6)所谓拥塞避免算法就是:每经过一个往返时间,就把发送方的拥塞窗口cwnd+1,即让拥塞窗口缓慢地增大,按照线性规律增长(由指数增长转为线性增长);当出现网络拥塞,比如丢包时,将慢开始门限设为原先的一半,然后将cwnd设为1,执行慢开始算法(较低的起点,指数级增长);
(7)该算法目的是在拥塞发生时循序减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。慢开始和拥塞控制算法常常作为一个整体使用。
2.快重传&快恢复
快重传和快恢复则是为了减少因为拥塞导致的数据包丢失带来的重传时间,从而避免传递无用的数据到网络。快重传的机制是:
(1)接收方建立这样的机制,如果一个包丢失,则对后续的包继续发送针对该包的重传请求
(2)一旦发送方接收到三个一样的确认,就知道该包之后出现了错误,立刻重传该包;
(3)此时发送方开始执行“快恢复”算法:
*1. 慢开始门限减半;
*2. cwnd设为慢开始门限减半后的数值;
*3. 执行拥塞避免算法(高起点,线性增长);