TCP小知识

来源:互联网 发布:java程序员兼职 编辑:程序博客网 时间:2024/06/05 05:47

转载自:http://jm.taobao.org/2017/06/01/20170601/

什么是delay ack

TCP是可靠传输,可靠的核心是收到包后回复一个ack来告诉对方收到了。

delay ack是指收到包后不立即ack,而是等一小会(比如40毫秒)看看,如果这40毫秒以内正好有一个包发给client,那么这个ack包就跟着发过去,而不需要增加任何大小,这样节省了资源。当然如果超过这个时间还没有包发给client,那么这个ack也要发给client了(即使为空,要不client以为丢包了,又要重发)。

假如这个时候ack包还在等待延迟发送的时候,又收到了client的一个包,那么这个时候server有两个ack包要回复,那么os会把这两个ack包合起来立即回复一个ack包给client,告诉client前两个包都收到了。

也就是delay ack开启的情况下:ack包有顺风车就搭;如果凑两个ack包自己包个车也立即发车;再如果等了40毫秒以上也没顺风车,那么自己打个车也发车。


什么是Nagle算法

如果要发送的数据大于最大传输包(MSS)的话,立即发送;否则,看看前面发出去的包是不是还有没有ack的,如果有没有ack的,那么这个小包不急着发送,等前面的ack回来再发送。这样可以优化带宽利用率,Nagle算法也是用来优化改进tcp传输效率的。Nagle算法一般默认开启的。


如果client启用Nagle,并且server端启用了delay ack会有什么后果呢?

假如client要发送一个http请求给server,这个请求有1600个bytes,握手的MSS是1460,那么这1600个bytes就会分成2个TCP包,第一个包1460,剩下的140bytes放在第二个包。

第一个包发出去后,server收到第一个包,因为delay ack所以没有回复ack,同时因为server没有收全这个HTTP请求,所以也没法回复HTTP response(server等一个完整的HTTP请求,或者40毫秒的delay时间)。client这边开启了Nagle算法(默认开启)第二个包比较小(140<MSS),第一个包的ack还没有回来,那么第二个包就不发了,等!互相等!一直到Delay Ack的Delay时间到了。


再来看一个经典例子和数据分析

这个案例来自:http://www.stuartcheshire.org/papers/nagledelayedack/

案例核心奇怪的问题是,如果传输的数据是 99,900 bytes,速度5.2M/秒;如果传输的数据是 100,000 bytes 速度2.7M/秒,多了10个bytes,不至于传输速度差这么多。

原因就是:

99,900 bytes = 68 full-sized 1448-byte packets, plus 1436 bytes extra100,000 bytes = 69 full-sized 1448-byte packets, plus   88 bytes extra

99,900 bytes时,68个整包会立即发送(都是整包,不受Nagle算法的影响),因为68是偶数,对方收到最后两个包后立即回复ack(delay ack凑够两个也立即ack),那么剩下的1436也很快发出去(根据Nagle算法,没有没ack的包了,立即发)。

100,000 bytes时,前面68个整包很快发出去也收到ack回复了,然后发了第69个整包,剩下88bytes(不够一个整包)根据Nagle算法要等一等,server收到第69个ack后,因为delay ack不回复(手里只攒下一个没有回复的包),所以client、server两边等在等,一直等到server的delay ack超时了。

原创粉丝点击