作者回复: 好问题:) 我们可以参考比较新的RFC5681(写于2009年),它的建议(这里不是样的规定)是: The initial value of ssthresh SHOULD be set arbitrarily high (e.g., to the size of the largest possible advertised window), but ssthresh MUST be reduced in response to congestion. 意思是初始慢启动阈值可以大胆一点设置为一个很大的值。当遇到拥塞的时候(超时或者3个DupAck),慢启动阈值会减为当前这个拥塞点的拥塞窗口的一半,这个时候的慢启动阈值,就是适配了实际情况的值,而不是最初那个大胆设置出来的值。 所以,首次慢启动后一般不会主动进入拥塞避免,而是等出现拥塞才获取到第一个实际可用的慢启动阈值。 你可以理解为: 1. TCP传输开始后进入慢启动,因为初始值很高,一般不进入拥塞避免 2. 如果达到了对方的接收窗,就维持在这个速度,然后 2.1如果遇到3次DupAck,那么 2.1.1 如果是TCP Tahoe这种老算法,再次进入慢启动然后拥塞避免 2.1.2 如果是其他算法,进入快速恢复 2.2如果拥塞是超时,则进入慢启动然后拥塞避免
作者回复: 您好: 1. 探测到拥塞,一般是两个条件,一是超时,一是收到3个DupAck。两者都表示传输出现了问题。你提到的“接收方的接收窗口与in flight数据大小”,如果在途数据等于对方的接收窗口,传输会是匀速进行了,也不属于拥塞,但无法继续增大拥塞窗口和发送窗口。你可以参考第9讲的案例。 2. 超时是动态计算的,因为每个场景下的RTT都不相同(而且同个连接的RTT本身也会动态变化),因此计算出来的RTO也不相同。不过RTO一般有个最小值,Linux的RTO最小值是200ms。
作者回复: 这确实是一个应该关注的知识点。慢启动阶段的“拥塞窗口翻倍”是一种表现,但不是规定。规定是“每收到一个ack,拥塞窗口就增加一个MSS”。比如: 初始拥塞窗口为10MSS;假如每次都有足量的数据要发送,那么: 第一次往返:发出10个MSS, 收到10个Ack,此时拥塞窗口增长为10+10也就是20个MSS 第二次往返:发出20个MSS,收到20个Ack,此时拥塞窗口增长为20+20也就是40个MSS 上面这种就是“翻倍”,但注意,RFC不是说一定要在一个RTT里面翻倍,而是因为一个RTT里经常收到跟发送量同等数量的Ack,所以效果上是翻倍的。
作者回复: 可以啊,本来就是双方各自用自己的拥塞控制算法的。你可以想象一下,一个服务端要跟那么多客户端通信,这些客户端也没有“说好了用同一种拥塞控制”,对不对:)
作者回复: 嗯所以TCP就设计了拥塞避免这种机制,为了让网络使用尽可能的公平。生活中也是,不排队随便挤的话反而慢,排队来反而快。TCP拥塞控制也是类似,有了规矩,不随意争抢,大家的机会就会比较均等:)
作者回复: 您好,这个问题倒不复杂,SMA period选项也没几个,你可以都试一下,看看出来的图是否比较“细腻”。一般来说,SMA period数值越小,出来的图的粒度越细腻;数值越大,粒度越粗,越会损失一些细节。 相对来说,建议选择小一些的SMA period值。
作者回复: 很好的笔记和打卡,加油:)