1. TCP header

想理解TCP的一切,了解他的header是最重要的(见下图)

src port 和 dst port是用来区别application层的分发

seq num 和 ack num 是为了实现“可靠传输(reliable transfer)” 

Flags有诸多的bit,比如我们TCP建立链接使用的SYN,断开的FIN,或者是ACK。flags 共 6bit

Receive window是用来告知server剩余传输的大小,实现flow control

一文看完TCP layer4(python代码) -- 其实没有那么复杂

2. TCP的三次握手和四次挥手

网上教程实在太多,我也不想赘述了,放一张状态转换图,搞懂了秒杀一切面试题。

⚠️为什么TIME_WAIT --> CLOSED 需要two segnment lifetime?

答:由于client申请了关闭,根据4次握手,client最后会针对于server的FIN包,回送一个ACK。而timeout是为了确保server不会回传FIN,即最后一个ACK被成功接收。

一文看完TCP layer4(python代码) -- 其实没有那么复杂

3. TCP的两大算法部分

FLow control和congestion control可以说是TCP的两大关键问题,本小姐主要讲Flow control,将congestion control留到下一节。、

Flow control用到的是sliding window的相关算法

我们可以看到,两边都有三个指针。

(a) 是server端,我们将server当前允许发送的packets数量定义为EffectiveWindow

(b) 是client端,也就是我们的接收端,我们定义当前允许被接收的数量为AdvertisedWindow(是不是发现和上文提到的header其中之一Receive window一样,没错,世界线收束)

举个例子:

假如有一天我的支付宝被设置了上限,只能存2000块,超过了就会被黑客转走。我是一个学生,也是client端。我的父母每个月给我生活费,也就是server端。

月初,我花了500块买了动物之森,然后我发现,我如果想一直保持两千块的总额,我还可以跟我爸妈要500块,这里的500块就是AdvertisedWindow。我爸妈每个月赚1000块,我和爸妈之间用来沟通转钱的速度的算法,就是flow control。我爸妈根据1000块的工资以及我告诉他们的AdvertisedWindow,决定先转我300块,这个300块,就是他们实际传输的量,也就是EffectiveWindow

一文看完TCP layer4(python代码) -- 其实没有那么复杂

一文看完TCP layer4(python代码) -- 其实没有那么复杂

一文看完TCP layer4(python代码) -- 其实没有那么复杂

关于window的大小,其实也有一个很有意思的说法。

如果sending window = receive window,我们要保证sending window < (max seq # + 1) /2

如果sending window = seq num,如下图,假如第一次所有的ACK都丢弃了,sender会重发6个packets。而被receive认为是新的6个packets,因为sequence num是循环的(因此sequence部分在header中是固定bit长度,是不是越来越觉得header是重中之重?)

一文看完TCP layer4(python代码) -- 其实没有那么复杂

4. TCP Tahoe -- TCP Reno -- TCP Vegas的创新历程

如何根据RTT计算选取一个合适的timeout是非常重要的问题。

最早的timeout计算方法是EWMA(exponentially weighted moving average),这也是我后面python project中用到的

接下来Karen-Patridge对其进行了优化:1. 假如重传(retransmit),那么sampleRTT作废。 2. 每次重传都对timeout * 2,这是一个保守的算法。

来自UCB的van jacobson发现了congestion的问题,提出了三个观点:这也是TCP Tahoe

Sending window = min(Congestion window, advertise window)

1. 新型的数学计算timeout

2. AIMD(Additive Increase Multiple Decrease): 增长时+1,loss是对半减少

3. Slow Start:刚一开始和loss之后,都指数倍增加,直到threshhold(equals 1/2 SendWND)开始AI

这是jacobson算法的图

一文看完TCP layer4(python代码) -- 其实没有那么复杂

下一款TCP reno更新了两个点:

1. fast retransmit:我们不再等待完全的timeout(也叫粗颗粒timeout),而是等到了3个duplicate ACK,就可以重传。并且

2. fast recovery:有loss之后,不再把Congestion window设置成1,而是设置成1/2 sending window, 然后执行AIMD中的AI

一文看完TCP layer4(python代码) -- 其实没有那么复杂

到了这里,我们发现,上述的算法都在研究“发生了congestion”如何应对。TCP vagas告诉我们“如何避免”

关于“如何避免”,这里有两种方法

1. host-based:TCP vagas 即host端进行计算,主动控制发送速率,但是并没有使用,原因是OS层面测量RTT的差别太难了

2. router-based: RED (Random Early Detection), 根据router的queue size来判断是否drop或者通知host,使host降低sending rate

相关文章: