UDP老丢包咋办?

最近公司一个网关项目出现概率性问题,WiFi网关发消息给终端设备时概率性丢包,导致有些控制消息没有执行。

产品结构框图

产品结构图如上,一次对家电的过程消息先由手机发给云端服务器,云端服务器处理后发给网关,网关发给家电。

Bug分析过程

从网关到空调这一段使用的是UDP通信方式,出现了概率性丢包。

什么时候会出现此bug?当云端下发的控制消息只是一条时,没问题,当云端连续下发三条控制消息时容易出现此问题。

1、是因为UDP通信方式不可靠导致丢包?如何复现?

网关和设备之间用的是UDP通信,当把每条下发消息一律重发三次反而更容易丢包了!但是,UDP真的那么容易丢包吗?这也在无意中复现了此问题,说明确实是UDP丢包引起的。

2、上报数据量太大了? 

一开始怀疑是数据量太大导致丢包,特别是开机时,上报的数据量很大,要把设备的所有状态上报,其中有大量的冗余不需要的数据,去掉这些冗余数据,好多了,丢包现象大大减小,但是仍然还是存在。

3、改成根据ack 判断是否重发呢?     

第1步中所有消息不管三七二十一 一律发3遍,效果反而不好,而这些发下来的不同消息之间如果延时一点时间又会有改善,所以是发下来的消息太快太多了?协议中每条发下去的消息对方收到后都会回复ack消息,此时把ack用起来,消息发出后1s如果还没收到ack那么重发这条消息,再过1s如果还是没有收到ack继续重发,直到收到ack为止,如果已经收到了那么不再管他。这样做了后效果并不理想,很多消息都会循环的重发,甚至重发了好多次才能收到ack。

(此处插一句,Handler模块可以很好的实现如果1s后没收到ack则再次重发该消息,如果收到了则不再重发这个功能,Handler是安卓里面用到的一个消息收发模块,支持发送后延时处理,从队列remove某消息,remove all等功能)。

难道这些消息其实都收到了只是返回的ack包丢了只是误判了丢包?从调试的现象看似乎已经不是因为UDP本身不可靠引起的丢包了,UDP再不可靠就这么点数据量也不应该这么容易丢包啊! 

4、UDP数据收发放一个线程互相阻塞了?

网关端UDP线程代码主循环结构如下:

判断是否有数据收到用的是select,select设置超时时间是500ms,是不是下发UDP消息影响了UDP收数据?把上面红色部分发消息的处理单独起一个线程,还是有问题。

难道是家电端TCP/IP协议栈有问题导致没收到?还是网关端协议栈有问题?天呀那问题就大了!

5、家电端udp数据收发时序有没有问题?

检查家电端wifi板程序,发现UDP数据处理函数没什么问题,但函数外面调用完有一个500ms的延时,整体结构如下:

这里delay 500ms会不会有问题?会不会耽误数据及时收到?

去掉500ms延时看看?去掉之后,就再也没出现丢包了!网关端加大下发的数据量中间不间隔都没有丢包了。

说明是这个500ms延时造成的!

数据到了后先存在传输层socket缓存中,应用层调用了recvform接口后数据由传输层传给用户应用层程序,传输层清空缓存。如果应用层线程在那里睡觉(delay 500ms)不及时去取数据,那么数据多的时候传输层buffer溢出,就造成了数据丢失了。

那么如果把socket缓存加大是不是该问题也能解决?后来没有试,有时间再试试。

结论

UDP线程中外循环的延时导致传输层中数据积压,没有及时被应用层收到,缓存溢出,导致丢包了。

总结

1、对于无线数据通信,最重要的是什么?时效性,也就是有数据来时需要你马上就能收到,无数据时你可以睡觉,但是有数据来时你必须立刻马上去收,不能睡觉!

那为了能及时收到数据,UDP线程一直不停地在那里读socket可以不?不行,因为一直占着CPU,别的线程得不到执行。

所以用select最好,设置超时时间,如果有数据马上就能收到,如果无数据等待一个超时时间就退出,具体实现可以网上百度看看。

2、重构代码仔细仔细再仔细,对比原代码看看到底做了什么改变!

追溯代码变化历史发现最开始UDP单独一个线程并没有这个延时,后来为了省内存与另一个线程合并,另一个线程有延时!所以代码重构不够仔细,无意间改变了时序引起了bug!

3、UDP协议对于重要的不能丢的消息一定要有重发机制,玩UDP没有做重发就是不专业, UDP是面向无连接的传输层通信协议,不保证数据可靠到达,仅仅是把到达主机的数据根据sokcet端口号分给不同进程。

1.零基础让普通MCU跑人工智能!法国AI创企开发无监督学习软件系统

2.反对人工智能的九条意见!

3.看直播赢好礼丨各路大咖为您解读《疫情当下,物联网与嵌入式系统的思考》

4.STM32系统中的2种数据掉电保护方法!

5.如何学会所有的编程语言?

6.VSCode和SourceInsight,到底哪个看源码爽?

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值