可靠传输
可靠传输基于滑动窗口
存在两个窗口,允许发送窗口和允许接收窗口,
接收窗口当且仅当前缀完全收到才能右移
发送窗口需要发送且收到确认才能右移(右端点不一定会移动,这取决于窗口值)
当确认丢失时需要采用超时重传的机制
超时重传的时机依靠RTT
RTTs样本计算:$RTTs=(1-α)RTTs+αRTT$
超市计数器时间RTO计算:$RTO=RTTs+4RTT_D$
其中偏差值$RTT_D=3/4RTT_D+1/4|RTTs-RTT|$
流量控制
流量控制基于rwnd
注意rwnd的值仅在ACK=1的情况下生效
当rwnd=0时接收方(指接收rwnd值的一方,平时是作为发送方)需要等待发送方一个新的窗口值才会继续发送流量
一种情况:B发送rwnd为0后,发现内部存在缓存可用,重新发送窗口值后丢失了,产生死锁
解决方法:持续计数器,当且仅当rwnd=0时启动,到期则发送1B大小的零窗口探测报文(接收rwnd一方发出),若得出值为0则维持现状,reset计数器,否则解除死锁
TCP传输的时机有
-
到达MSS
-
push
-
TCP内部有缓存且到达计数时间
解决小报文段的捎带传输的实现:
Naggle算法: 1.发送第一个数据字节,后面的进行缓存
2.收到该字节的确认后,把缓存所有字节发送出去,随后到达的继续缓存
3.收到前面的确认后再以此类推
此时可改良网络速率慢而数据到达速率快的情况,并且能捎带传输(先缓存下来而不是急于发送)
拥塞控制
发送发维护拥塞窗口cwnd,且让发送窗口值等于cwnd
判断拥塞依据:路由器的分组丢弃导致的超时
- 慢开始
避免开始把大量数据注入网络,cwnd设置为2-4个SMSS
且每次cwnd增加量=MIN(N,SMSS),N为刚确认的字节数
一个轮次需要一次RTT时间,每次都会把cwnd翻倍
细节:并不是RTT过后直接倍增,是收到一个确认立刻增加对应的大小,详看页尾注释
- 拥塞避免
1.慢开始过程具有门限ssthreash,一旦cwnd超过该门限则进入拥塞避免算法,进行线性递增,使网络不易拥塞
2.当出现超时(认为拥塞)时,ssthresh折半且cwnd=1,回到慢开始环节
- 快重传
为了尽早让发送方得知个别报文丢失而不是误判为拥塞,接收方不使用捎带确认的缓存算法,而是立即发送确认(失序也要)
比如2 4 5 收到,认为3丢了,会发送2的确认,此时2的两次确认(4没确认)表示3丢了,往后5也会发送2的重复确认,当ACK达到3时发送方确信是丢失了而立刻重发(3-ACK)
- 快恢复
当得知只是部分丢失时,发送发直接把ssthread=cwnd/2且cwnd=ssthread,直接进入拥塞避免过程
四个阶段的优化
1.慢启动过程对高RTT不友好,可以把cwnd适当加大
2.避免超时重传可采用受限传输机制:发送方至少接收到一个重复ACK才传输新的数据报文段 (公平队列。。。)
BBR原理
组成
-
即时带宽
-
RTT跟踪
-
pipe状态机
-
pacing rate和cwnd
BW计算
$BW=delivered/interval_{us}$
其中delivered是应答数据的个数,interval_{us}是应答所用的时间
其中应答部分不区分是正常发送还是重传
pacing rate和cwnd计算
$pr=G \cdot BW$,$G$为增益系数
BBR中RTT只论曾经到达的最佳RTT,而不会加权平均(目标是再次令RTT最小)
此时$cwnd = G' \cdot BDP$
其中BDP为带宽和时延的乘积
G和G'由BBR状态机给出
状态机
每一次ACK都会计算BW,且把结果反馈给pipe状态机,从而得到G和G'
注意状态机的多种状态是具有一定针对性的,这里不展开
补充说明
传统TCP中输出只有cwnd,而BBR还多输出了一个pacing rate,用于控制cwnd的发送情况,前者会在cwnd富裕的情况下一并发出,而后者是根据pacing rate表示窗口内的数据包以多久的时间间隔发送,减少RTT抖动的可能性