UDP老丢包咋办?

UDP老丢包咋办?

时间:2020-03-26 13:21 作者:admin 点击:
阅读模式 (此处插一句,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,到底哪个看源码爽?

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