博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP/IP之(四)Delay ack 和 Nagle算法
阅读量:7187 次
发布时间:2019-06-29

本文共 1329 字,大约阅读时间需要 4 分钟。

Delay ack(延迟确认)

正常情况下服务器收到一个请求时就会立即回复ACK确认给客户端,然后客户端再发送下一个包,服务器再进行回复。有时候服务器回复的ACK包有长度,但实际内容长度为0,这也没关系属于正常的。不过一次发送一次确认效率比较低,能不能收多次批量确认一次呢?这就是延迟确认。

Delay ack是说收到包不立即回复ack,而是等一会儿默认200毫秒,看看这段时间是否有还有包发过来(属于同一客户端)如果有就一起发送ACK确认,如果超时了还没有等到那么就直接发送这一个确认包。在延迟确认期间ack不是立即发送而是等待200毫秒,如果有就一起发送,或者如果凑够2个ack包就一起发送;如果在等200毫秒还没有就发送者一个ACK包。

所以正常情况下抓包都是一个数据包后面紧跟一个ACK确认包。


Nagle算法

如果服务器接收窗口大于MSS并且客户端要发送的数据大于一个MSS长度(1460)的就立即发送;否则就等待前面发出去包是不是还没有ACK,如果没有剩下的小包就等前面的ack返回之后再发送。也就是说包很小,然后又有包发给服务器而且还没有收到ack,那么就等等ack返回之后再发送剩下的包。


如果客户端启用Nagle并且服务器启用了delay ack会怎么样?

比如客户端发送一个HTTP请求给服务器,这个请求有1560个字节,握手的MSS是1460个字节。那么这1560个字节就会分成2个TCP包,第一个1460,第二个100。第一个发送出去后,服务器收到,因为延迟确认,服务器等待200毫秒,客户端开启了Nagle(默认开启)由于第二个包100字节很小,所有它就等待前一个包的ack返回后再进行发送,这时双方就进入互相等待的阶段,直到200毫秒超时,服务器发送ack,然后客户端再发送剩余的一个包。


再说一个例子引用自:

传输数据是99,900字节,速度5.2M每秒;如果传输数据是100,000字节速度是2.7M每秒。多了10字节为什么速度下降这么多?

99,900 bytes = 68 全尺寸包 1448字节每个包,另外剩余1436字节最后一个包
100,000 bytes = 69 全尺寸包 1448字节每个包,另外剩余88字节最后一个包

说明:一个MSS是1460,为什么上面一个包是1448呢?因为那12个字节,因为Windows操作系统是1460,苹果或者其他操作系统多了一个时间戳选项,TCP分段大小就少了所以是1448个字节。上面的例子是按照Linux操作系统来说的。


68个包会立即发发送,因为68是偶数,所以服务器最后肯定收到2个包,然后发送ACK给客户端,然后客户端立即发送剩余的1436字节,整个过程没有等待。如果是69个包由于是奇数,服务器最后一次收到是1个包,所以等待200毫秒,然后客户端由于剩下88个字节也会等待,这样就增加了整体传输时间,超时之后再发送最后一个88个字节。


上图是传输100,000字节

上图是传输99,900字节

      本文转自linuxjavachen  51CTO博客,原文链接:http://blog.51cto.com/littledevil/1966546,如需转载请自行联系原作者
你可能感兴趣的文章
zookeeper原理(转)
查看>>
垂直居中的几种方法
查看>>
我的友情链接
查看>>
PTN960
查看>>
$_FILES[‘file’][‘error’] 错误代码和相关的错误常量
查看>>
将项目加入maven管理时报错
查看>>
Qt线程
查看>>
数据库小知识
查看>>
ASP.NET WEB API必知必会:特性路由
查看>>
'Worker' object has no attribute '_config'
查看>>
微信支付开发H5调用支付接口失败
查看>>
IIS安装及IIS无权访问解决方法(Failed to access IIS metabase解决)
查看>>
Oracle下ORA-28002错误处理
查看>>
新方法让纳米材料组装合成“指哪长哪”
查看>>
springboot及微服务
查看>>
【unity】手势操作之初识FingerGestures
查看>>
nginx配置url重定向-反向代理
查看>>
MySQl的备份和恢复(笔记2)
查看>>
打算做一个网站
查看>>
18大解读
查看>>