解决 QT udp接收不到数据包问题

本次记录了两Qsocket的问题。

问题一描述:

QUDP一开始就接收不到数据,通过bool打印connect是成功连接的,readyRead也响应,但就是收不到数据。

UdpCommunication::UdpCommunication(QObject *parent)
    :QObject(parent)
{
  	udpSocket = new QUdpSocket(this);
    qint16 port;
    port = 8806;
    udpSocket->bind(QHostAddress::AnyIPv4,8806);
    connect(udpSocket, &QUdpSocket::readyRead, this, &UdpCommunication::unicastRev);
}

1.1最终找到了问题所在:

原因是调用 writeDatagram() 发送数据包时,程序不知道有没有发完,会一直指向这里,相当于阻塞了。
即使socket信号readyRead()发送了,也不会调用接收函数readDatagram();所以导致接收端一直接收不到数据。
需要在发送的时候调用udpSocket->waitForReadyRead(100);告诉程序发送完毕。目前发现在windows下会出现这个问题。

1.2示例:

UdpCommunication::UdpCommunication(QObject *parent)
    :QObject(parent)
{
  	udpSocket = new QUdpSocket(this);
    qint16 port;
    port = 8806;
    udpSocket->bind(QHostAddress::AnyIPv4,port );//绑定本机发送的端口,否则随机端口发送
    udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);//绑定本机端口
    connect(udpSocket, &QUdpSocket::readyRead, this, &UdpCom::unicastRev);
}
	//发送
 	udpSocket->writeDatagram((char *)sendBuff, 2, QHostAddress::Broadcast, CONNECT_PORT_SEND);
    udpSocket->waitForReadyRead(100);//结束发送,等待读取
//接收
	QByteArray array;
    QHostAddress address;
    quint16 port;
    array.resize(udpSocket->bytesAvailable());//根据可读数据来设置空间大小
    udpSocket->readDatagram(array.data(),array.size(),&address,&port); //读取数据

问题二描述:

程序运行一段时间,readyRead不响应,无法接收数据的问题。
本人猜测udpsocket缓存接收中,有数据我没有接收完,导致readyRead不响应。

2.1readyRead的触发机制

1)readyRead信号触发是在QTcpSocket缓存接收到新的数据时,并不等同于发送端write函数调用一次。
2)当数据从系统缓冲区到QTcpSocket缓存时,readyRead信号触发一次。如果此时readyRead槽函数还没有及时执行,又有新的数据到来了,而且来了很多次(QTcpSocket缓存还没满的情况,满的情况下系统不再发数据给应用),那么这些所有的都将会只触发一次readyRead信号。
3)当数据从系统缓冲区到QTcpSocket缓存时,readyRead信号触发一次。如果此时readyRead槽函数执行了,后续再来的新数据,将会触发新的readyRead信号。但这个QTcpSocket连接中,还没有响应的readyRead信号最多只有两个。

2.2于是在这次问题的解决办法是:

关闭连接,重新建立连接。

 if(udpsocket->bytesAvailable()!=0)
     {
         qDebug()<<"接收不到数据,重启";
         udpsocket->close ();
         udpsocket=new QUdpSocket(this);
         udpsocket->bind (1234,QUdpSocket::ShareAddress);
         connect (udpsocket,&QUdpSocket::readyRead,this,&UdpCom::unicastRev);
     }

若接收数据正常,udpsocket->bytesAvailable()的值将为0,接收不到数据则为非零值,这样就可用个定时器,循环检测下,若不为零,将SOCKET重启即可。

虽然挖到了QUDP的比较底层的原理,其实我感觉这个解决办法并没有解决根本原因,如果真的是缓存有数据没取完,是什么原因造成的,还得继续深挖。怎么说呢,这个问题也算是解决完了,不然一直卡着也不行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值