频道栏目
首页 > 资讯 > 微信公众平台开发 > 正文

TCP DUP ACK的研究

18-04-27        来源:[db:作者]  
收藏   我要投稿

最近在跟一个CDN服务器端做对接,从CDN服务器下载内容(http),发现抓包出现非常多的Tcp Dup Ac​k异常提示。通过查阅质料得知Tcp Dup Ack xxx#y 代表了数据段丢失TCP状态,xxx代表数据丢失的位置,#后代表第几次丢失文。然后我我又再看了下报文,的确是2次数据发送到我这边,我才回复一次ack,但是这个ack回复是正确的

。 对比对接其他地方的CDN的抓包,发现却是1次数据过来,回复一次ack,但是为什么对接这个CDN确实2次回复一个ACK呢?通过详细的对比报文,发现了问题所在。

TCP头部有一个标志位字段:

URG:紧急指针(urgent pointer)有效。

ACK:确认序号有效。

PSH:接收方应该尽快将这个报文段交给应用层。

RST:重建连接。

SYN:发起一个连接。

FIN:释放一个连接。

然而正常HTTP给数据的时候,这个标志位是ACK+PSH,但是这个CDN给数据的时候,却还是ACK,并没有带PSH。

TCP在处理交互数据流(即Interactive Data Flow,区别于Bulk Data Flow,即成块数据流,典型的交互数据流如telnet、rlogin等)时,采用了Delayed Ack机制以及Nagle算法来减少小分组数目。

对于非交互应用应该禁止NAGLE算法,设置 TCP_NODELAY,

const char chOpt = 1;

int nErr = setsockopt(pContext->m_Socket, IPPROTO_TCP, TCP_NODELAY, &chOpt, sizeof(char));

TCP延时确认时间通常为40毫秒(#define TCP_DELACK_MIN ((unsigned)(HZ/25)) ),如果在延迟时间内有报文段要发送的话,ack附加到数据报文段一起发送;如果没有,那么当延迟时间到时,就单独发送ACK。

所以,当对方只带ACK而不带PSH的时候,系统认为这个是交互信令,从而延时回复。在第二次数据到来的时候一次性回复了。这个时候如果对方CDN对数据传输回复要求很严格,就会存在对方及时得不到ACK回复的问题。所以就会发送TCP DUP ACK过来了。

解决办法:

通过查阅资料,可以在每次recv到数据后,调用一次setsockopt函数,设置TCP_QUICKACK

setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, (int*)(1), sizeof(int));

TCP_QUICKACK为值为12。

通过这个设置之后,每一个报文都及时回复了ACK。解决了这个TCP DUP ACK问题。

相关TAG标签
上一篇:MySQL学习笔记5:子查询与连接
下一篇:微信开发教程之申请服务器资源
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站