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
2. TCP的三次握手和四次挥手
网上教程实在太多,我也不想赘述了,放一张状态转换图,搞懂了秒杀一切面试题。
⚠️为什么TIME_WAIT --> CLOSED 需要two segnment lifetime?
答:由于client申请了关闭,根据4次握手,client最后会针对于server的FIN包,回送一个ACK。而timeout是为了确保server不会回传FIN,即最后一个ACK被成功接收。
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
关于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是重中之重?)
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 reno更新了两个点:
1. fast retransmit:我们不再等待完全的timeout(也叫粗颗粒timeout),而是等到了3个duplicate ACK,就可以重传。并且
2. fast recovery:有loss之后,不再把Congestion window设置成1,而是设置成1/2 sending window, 然后执行AIMD中的AI
到了这里,我们发现,上述的算法都在研究“发生了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