QT中UDPSocket丢包问题

来源:互联网 发布:淘宝网小饰品批发 编辑:程序博客网 时间:2024/06/05 02:42

1.配置和编程

下位机向上位机发送UDP数据包,由于UDP小包不能写太大,每个小包也就1kB左右。

下位机周期性地发送数据,每个周期发送数百个udp包,并且是使用while死循环来发送的。

上位机使用QUdpSocket类接收UDP数据。采用信号-槽的机制,信号使用socket的readyRead,来通知函数接收数据。

2.现象

在上位机上使用wireshark监测接收到的数据包,发现在4-5个ms内收到两百多个udp小包,相邻小包的时间间隔在几个us。

使用QT编写的软件接收数据,出现严重的丢包现象。二百多包数据,每次仅能收到一半左右的数据包,并且这个数量是不固定的。

3.初步解决

查询网上资料,有很多人遇到了这个问题,一种观点认为:

在Windows下,QT对udp socket的支持较差,建议使用WinSocket。QT在Linux下对udp socket的支持较好。

于是进行了以下改进:

(1)操作系统变更为Linux

(2)摒弃了信号-槽的方式,在程序中新开了一个线程,在线程中利用while循环来接收数据。基本的代码如下:

    while(1)    {        while( p_socket->hasPendingDatagrams())  // 有数据        {            net_pack_size = p_socket->pendingDatagramSize();            p_socket->readDatagram((char*)p_net_pack,net_pack_size);    // 补充其他处理:数据存储等        }    }

4.测试情况及问题

(1)在Linux下,不丢包了。但有CPU上有一个核始终占用100%。

(2)在Windows下,仍然存在丢包的现象。只有一次瞬间发送udp小包在64包以下时,才不丢包。

5.思考及后续解决方案

(1)Qt的UDP Socket不能使用阻塞模式,所以不丢包的代价就是使用while死循环收数,CPU占用率100%,并且还得是Linux系统。

(2)拟采用原始的Socket处理函数,或在Windows下使用WinSocket库来改进。改进结果尚不清楚,后续仍会跟进。

[20170524]

原创粉丝点击