Hi everyone
This is my first post here and I can see its a question that has been raised a number of times. It concerns the reliability of the QUdpSocket. I've read other posts on the subject, but got various suggestions but no definitive answers, so I'll explain my problem here ...
I have an application created in Qt5.5 running on Ubuntu14.04. Its receiving small udp datagrams from a remote device. The datagrams are all less than 15 bytes of data. The datagrams normally arrive about once per second, but every few seconds two datagrams will arrive in quick succession. I can monitor on Wireshark, and these two quick datagrams are logged about 5msecs apart.
My application code is based exactly on the QUdpSocket example in Qt documentation, (see below) and its all running in the main GUI thread.
void Server::initSocket()
{
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}
void Server::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
datagram.resize(udpSocket->pendingDatagramSize());
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
processTheDatagram(datagram);
//additional debug code
qDebug() << "Bytes available = " << udpSocket->bytesAvailable();
}
}
void Server::initSocket()
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}
void Server::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
processTheDatagram(datagram);
//additional debug code
qDebug() << "Bytes available = " << udpSocket->bytesAvailable();
}
}
To copy to clipboard, switch view to plain text mode
My application can run for days with no problem then it just stops receiving datagrams. I am aware of the nature of the readyRead() signal being not being processed if it occurs during the readPendingDatagrams() slot, and the code seems to take care of this successfully using the
while (udpSocket->hasPendingDatagrams())
{
}
while (udpSocket->hasPendingDatagrams())
{
}
To copy to clipboard, switch view to plain text mode
code to ensure any datagrams received while the slot is being processed are read in before exiting the slot.
I added in a qDebug() line at the end of the readPendingDatagrams() slot to check the operation of the slot.
As expected normally the qDebug message normally prints 'Bytes avalable = 0', except when the two datagrams arrive in quick succession the qDebug message then sometimes prints 'Bytes available = 4' correctly indicating the presence of my second 4 byte datagram which has subsequently arrived and is waiting to be processed. The readPendingDatagrams() slot then loops again to process that data. All good as expected
However, as already stated, my application just stops receiving randomly, somtimes a few times a day other times running for days with no problem. Every time the application fails its when the two datagrams are received in quick succession. I have now created a simple button on my user interface that can query the socket manually reading
udpSocket->bytesAvailable();
udpSocket->bytesAvailable();
To copy to clipboard, switch view to plain text mode
on demand.
Here is what I found...
When my application fails its always at the two quick succession datagrams.
The first datagram is always received successfully.
My
qDebug() << "Bytes available = " << udpSocket->bytesAvailable();
qDebug() << "Bytes available = " << udpSocket->bytesAvailable();
To copy to clipboard, switch view to plain text mode
prints 'Bytes available = 0', indicating the second datagram has not yet arrived, and the readPendingDatagrams() slot exits.
No other datagrams are received after this.
When the application stops receiving I can click the new button I have created and it reports that there are infact 4 bytes Available !!!!
It seems as though there is a moment, between where the readPendingDatagrams() slot checks for
udpSocket->hasPendingDatagrams()
udpSocket->hasPendingDatagrams()
To copy to clipboard, switch view to plain text mode
and where it finally returns, that the readyRead() signal from the next datagram can be asserted and missed.
Has any one else observed this, and is there a common remedy.
Bookmarks