Results 1 to 6 of 6

Thread: QUdpSocket readyRead failure

  1. #1
    Join Date
    Nov 2015
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default QUdpSocket readyRead failure

    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.
    Qt Code:
    1. void Server::initSocket()
    2. {
    3. udpSocket = new QUdpSocket(this);
    4. udpSocket->bind(QHostAddress::LocalHost, 7755);
    5.  
    6. connect(udpSocket, SIGNAL(readyRead()),
    7. this, SLOT(readPendingDatagrams()));
    8. }
    9.  
    10. void Server::readPendingDatagrams()
    11. {
    12. while (udpSocket->hasPendingDatagrams()) {
    13. QByteArray datagram;
    14. datagram.resize(udpSocket->pendingDatagramSize());
    15. QHostAddress sender;
    16. quint16 senderPort;
    17.  
    18. udpSocket->readDatagram(datagram.data(), datagram.size(),
    19. &sender, &senderPort);
    20.  
    21. processTheDatagram(datagram);
    22.  
    23. //additional debug code
    24. qDebug() << "Bytes available = " << udpSocket->bytesAvailable();
    25. }
    26. }
    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
    Qt Code:
    1. while (udpSocket->hasPendingDatagrams())
    2. {
    3.  
    4. }
    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
    Qt Code:
    1. 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
    Qt Code:
    1. 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
    Qt Code:
    1. 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.

  2. #2
    Join Date
    Nov 2015
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QUdpSocket readyRead failure

    177 reads, and ZERO replies !

    Did I, somehow, accidentally set the thread permissions as 'Read Only' ?

  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QUdpSocket readyRead failure

    Is the last datagram you receive intact and the size you expected?
    Does the program fail in the same way if you never call processTheDatagram()? Is the processing exhausting system resources over time causing the networking to fail as a side effect?

  4. #4
    Join Date
    Nov 2015
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QUdpSocket readyRead failure

    Hi ChrisW67

    Thanks for your reply.

    The last datagram received is always complete and the right size.
    I've never tried testing the program without processing the datagram. The program is essentially just about receiving these datagrams so does almost nothing without them.
    The process does not appear to exhaust system resources. The memory usage of the program is pretty consistant over days of running. I ran a 'Valgrind' test on it and it appears to have no memory leaks.

    The network does not actually fail. I can start up wire shark and see the datagrams arriving, they are just not firing the readyRead() signal.
    In my program, I can now check the status of the network socket on demand by clicking a button. When the program stops receiving datagrams, I check the socket status using
    Qt Code:
    1. udpSocket->hasPendingDatagrams()
    To copy to clipboard, switch view to plain text mode 

    it returns true.

    I also check
    Qt Code:
    1. udpSocket->bytesAvailable();
    To copy to clipboard, switch view to plain text mode 

    and that returns a value of 4, which is exactly the size of the next datagram. Its been received and is sitting there waiting to be read. It just didn't appear to send the readyRead() signal from the socket.

    I'm getting to the point where I think I need a timer to keep checking for this condition, but its not a nice solution at all.

    Anybody else using sockets and protect against this situation? Any suggestions wold be greatly appreciated.


    Added after 5 minutes:


    I created an account at the Qt Bug Tracker site this morning.

    https://bugreports.qt.io/secure/Dashboard.jspa

    I looked at the bug reports and there it is. Bug 46552 exactly what I am experiencing.
    A month or so ago I upgraded from Qt 5.2.1 to Qt5.5.0, and it appears this bug is in Qt5.4.2 and 5.5.0
    For anyone out there with these versions - BEWARE !
    Last edited by mike66; 23rd November 2015 at 02:23.

  5. #5
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QUdpSocket readyRead failure

    Quote Originally Posted by mike66 View Post
    177 reads, and ZERO replies !
    I have read your post multiple times and started multiple replies, only to cancel out once I realize I don't know what I'm talking about for certain, but here goes...

    You would have to inspect the QUdpSocket, QIODevice, and perhaps QAbstractSocket code to confirm this, but I can see where bytesAvailable, which is a QIODevice inherited method would have bytesAvailable but are somehow not yet readable by the socket. That may not make logical sense to you or I, but it all depends on how these methods are implemented of course.

    I see that @ChrisW asked and you confirmed that last datagram is always complete, with a payload of 4 bytes each time. I would suggest a couple of things to try:

    1) Eliminate the processTheDatagram function call in your loop, where you simply check for hasPendingDatagrams and then readDatagram to see if you continue to receive the readyRead signals. If so, then check processTheDatagram to see how/if you may be blocking the event loop, etc.

    2) If you have control of the sending program, pad that last payload to be a larger size, say 32 bytes as a guess just to see if you may have found some bug that exists with extremely small payloads. I would consider a complete payload of 4 bytes very small, especially when payloads typically contain some type of self describing information (packet type, length, etc) so that the receiving program can ensure complete packets are receive and not split, etc.

    Those are the two things I would do first to try to figure out what's going on. Hope that helps in some way!
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  6. #6
    Join Date
    Nov 2015
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QUdpSocket readyRead failure

    Hi Jefftee

    Thanks for taking the time to think about this problem and for your suggestions.
    However, at the bottom of my last post there are a few paragraphs ...


    I created an account at the Qt Bug Tracker site this morning.

    https://bugreports.qt.io/secure/Dashboard.jspa

    I looked at the bug reports and there it is. Bug 46552 exactly what I am experiencing.
    A month or so ago I upgraded from Qt 5.2.1 to Qt5.5.0, and it appears this bug is in Qt5.4.2 and 5.5.0
    For anyone out there with these versions - BEWARE !
    I'm actually upgrading to qt5.5.1 as it seems the bug has been fixed in the new version. Time will tell !

    But, thanks again for your input.

Similar Threads

  1. QUdpSocket readyRead() signal not triggered
    By deionut in forum Newbie
    Replies: 2
    Last Post: 26th October 2010, 19:19
  2. Not getting readyRead from a QUdpSocket
    By evelBist in forum Newbie
    Replies: 3
    Last Post: 20th July 2010, 20:43
  3. readyRead problem
    By fruzzo in forum Qt Programming
    Replies: 11
    Last Post: 2nd September 2009, 20:50
  4. QExtSerialPort with readyRead()
    By tho97 in forum Qt Programming
    Replies: 4
    Last Post: 27th August 2008, 21:18
  5. readyRead signal too slow or what?
    By Morea in forum Qt Programming
    Replies: 1
    Last Post: 6th July 2007, 20:11

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.