LWIP TCP接收端不主动发送ACK导致接收异常问题分析

1.问题场景描述

本机运行LWIP协议栈,作为TCP客户端负责接收数据,上位机使用标准TCPIP协议栈并使用socket套接字,作为服务器端按照100ms周期向客户端发送数据。通信链路为千兆以太网,且整个网络仅有两个节点。在数据交互的过程中发现,客户端的TCP链接不稳定,频繁与服务器端断开链接,无法正常接收服务器端的数据。

2.问题分析与排查

由于服务器端是使用标准socket套接字编程,且经过长期验证,因此问题出现点大概率为使用LWIP协议栈的客户端。排查过程中,首先将服务器端的数据速率由100ms降低为1s,结果发现客户端的链接基本稳定。然后,在上位机运行wireshark进行抓包分析,发现即使是在1s周期的条件下,服务器端发送的数据包并未收到客户端返回的ACK包,结果导致服务器端重传相同的数据包;将发送速率恢复到100ms周期后,发现服务器端由于未收到ACK包而大量地重传数据包,由于重传到一定量后服务器端仍旧未收到ACK包,因此服务器端主动关闭了该链路,也就说明了为什么客户端会发现链接不稳定。

3.问题解决

通过上述排查分析,基本可以定位到是由于客户端在收到报文后未向服务器端正确回复ACK报文导致的,因此查看客户端的LWIP TCP接收回调函数,发现内部确实没有任何返回ACK报文的语句。同时查找LWIP TCP相关资料,发现某些配置下,在接收到数据报文后并不会主动发送ACK报文,而是等待发送数据时将ACK一并带出。巧合的是,测试时客户端仅接收数据并未发送数据,所以就会出现不发送ACK的现象。通过查阅LWIP函数接口,发现了tcp_send_empty_ack()函数,从字面意思就能知道该函数的作用时发送一个空的ACK报文。因此在TCP接收回调函数中,收到数据报文之后,调用该函数进行主动发送ACK报文。添加后,发现在100ms或者更快的发送周期条件下,服务器端都能正常接收到来自客户端的ACK报文,从而不会频繁重发数据包。同时客户端的链接也稳定,不再出现频繁断开与服务器之间的链接的情况。

后记

出现网络问题,要及时使用wireshark等抓包工具进行抓包协助分析。其次,还要想办法搭建便于测试分析的测试环境,提高问题排查的效率。最后,还要进一步加强对TCPIP协议的深入学习与研究,打好基础才能快速分析定位问题。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weekman93

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值