Results 1 to 4 of 4

Thread: Problem writing too fast to QUdpSocket

  1. #1
    Join Date
    Apr 2020
    Posts
    3
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Problem writing too fast to QUdpSocket

    Hi,

    Using Qt 5.14.1.

    If I write back to back on a QUdpSocket, the subsequent datagrams never make it out. For example:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QUdpSocket>
    3. #include <QTextStream>
    4. #include <QThread>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QTextStream cout(stdout);
    9. QUdpSocket myUdpSocket;
    10.  
    11. myUdpSocket.connectToHost("127.0.0.1", 50000);
    12.  
    13. cout << myUdpSocket.write("msg 1\n") << Qt::endl;
    14. cout << myUdpSocket.write("msg two\n") << Qt::endl;
    15.  
    16. QThread::currentThread()->sleep(5);
    17.  
    18. return 0;
    19. }
    To copy to clipboard, switch view to plain text mode 
    Both writes return that they wrote the expected number of bytes (6 and 8).

    Per Wireshark, only the first write (i.e., "msg 1\n") is actually sent out.

    "1","0.000000","127.0.0.1","127.0.0.1","UDP","58", "54399 ? 50000 Len=6","msg 1\n"

    If I put in a delay, then it works:
    Qt Code:
    1. cout << myUdpSocket.write("msg 1\n") << Qt::endl;
    2.  
    3. QThread::currentThread()->sleep(1);
    4.  
    5. cout << myUdpSocket.write("msg two\n") << Qt::endl;
    To copy to clipboard, switch view to plain text mode 
    Wireshark output:

    "1","0.000000","127.0.0.1","127.0.0.1","UDP","58", "53420 ? 50000 Len=6","msg 1\n"
    "2","1.000014","127.0.0.1","127.0.0.1","UDP","68", "53420 ? 50000 Len=8","msg two\n"

    I also tried waitForBytesWritten(), and that didn't work (the calls to it each return false):
    Qt Code:
    1. cout << myUdpSocket.write("msg 1\n") << Qt::endl;
    2.  
    3. cout << myUdpSocket.waitForBytesWritten(1000) << Qt::endl;
    4.  
    5. cout << myUdpSocket.write("msg two\n") << Qt::endl;
    6.  
    7. cout << myUdpSocket.waitForBytesWritten(1000) << Qt::endl;
    To copy to clipboard, switch view to plain text mode 
    I am fairly new to Qt so my apologies if I am missing something seemingly obvious. Any help understanding why QUdpSocket and/or write() is behaving this way is greatly appreciated. Thank you.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,728
    Thanks
    13
    Thanked 1,608 Times in 1,535 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Problem writing too fast to QUdpSocket

    You are using the QIODevice interface. You are writing into a buffer (successfully) and leaving Qt to determine when the bytes actually go on the wire. In general this requires an application object and a Qt event loop to be running and you are providing neither.

    Try something like this:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QUdpSocket>
    3. #include <QTimer>
    4. #include <QObject>
    5. #include <QDebug>
    6.  
    7. class Sender: public QObject {
    8. Q_OBJECT
    9. public:
    10. Sender(QObject *p = nullptr):
    11. myUdpSocket(new QUdpSocket(this)) {
    12. myUdpSocket->connectToHost("127.0.0.1", 50000);
    13.  
    14. connect(myUdpSocket, &QUdpSocket::bytesWritten, this, &Sender::sentStuff);
    15.  
    16. QTimer::singleShot(0, this, &Sender::sendStuff);
    17. // ^^^ delays sending stuff until event loop is running
    18. // and this timer event is processed
    19. }
    20. ~Sender() { }
    21. private slots:
    22. void sendStuff() {
    23. qDebug() << myUdpSocket->write("msg 1\n");
    24. qDebug() << myUdpSocket->write("msg two\n");
    25. }
    26. void sentStuff(qint64 bytes) {
    27. qDebug() << "Bytes sent:" << bytes;
    28. }
    29. private:
    30. QUdpSocket *myUdpSocket;
    31. };
    32.  
    33.  
    34. int main(int argc, char *argv[]) {
    35. QCoreApplication app(argc, argv); // << application object
    36. Sender s;
    37. return app.exec(); // << event loop
    38. }
    39.  
    40. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to ChrisW67 for this useful post:

    mwvse (15th April 2020)

  4. #3
    Join Date
    Apr 2020
    Posts
    3
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problem writing too fast to QUdpSocket

    Thank you ChrisW67 very much for the reply. Using your code example with no modifications. I still get the same result.

    Here is my console output:

    consoleOutput.PNG

    And here is my wireshark output:

    wiresharkOutput.PNG

    Any other thoughts about this are greatly appreciated. Thanks.
    Last edited by mwvse; 15th April 2020 at 21:42.

  5. #4
    Join Date
    Apr 2020
    Posts
    3
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Solved: Problem writing too fast to QUdpSocket

    Thanks to the help from others on various forums, I believe the problem has to do with the following (at least under Windows):

    https://stackoverflow.com/questions/...p-sent-packets

    Here is an excerpt:

    Microsoft has addressed this type of UDP drops during ARP resolution in the past. It is possible/likely the behavior remains in current implementations.

    From ARP and UDP Messages

    ARP queues only one outbound IP datagram for a given destination address while that IP address is being resolved to a MAC address. If a UDP-based application sends multiple IP datagrams to a single destination address without any pauses between them, some of the datagrams might be dropped if there is no ARP cache entry present. An application can compensate for this by calling the Iphlpapi.dll routine SendArp() to establish an arp cache entry, before sending the stream of packets. See the platform Software Development Kit (SDK) for additional information.
    The following code delays after the first write, then runs 1000 at full speed and none of the writes get dropped. If you remove that first delay, only the first write gets sent out (even when using 127.0.0.1):

    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QUdpSocket>
    3. #include <QTextStream>
    4. #include <QThread>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QCoreApplication app(argc, argv);
    9.  
    10. QTextStream cout(stdout);
    11. QUdpSocket* myUdpSocket = new QUdpSocket;
    12.  
    13. myUdpSocket->connectToHost("127.0.0.1", 50000);
    14.  
    15. cout << myUdpSocket->write("msg 1\n") << Qt::endl;
    16. QThread::currentThread()->sleep(1);
    17.  
    18. for(unsigned u = 0; u < 1000; u++)
    19. cout << myUdpSocket->write("another\n") << Qt::endl;
    20.  
    21. QThread::currentThread()->sleep(5);
    22.  
    23. return 0;
    24. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Fast Data Colllection Buffering and File Writing
    By bob2oneil in forum Qt Programming
    Replies: 0
    Last Post: 18th April 2012, 23:12
  2. QUdpSocket problem MacOSX
    By kangy in forum Qt Programming
    Replies: 1
    Last Post: 11th March 2010, 07:06
  3. Replies: 14
    Last Post: 16th March 2009, 09:19
  4. fast writing of large amounts of data to files
    By TheKedge in forum Qt Programming
    Replies: 1
    Last Post: 13th February 2007, 16:33
  5. Replies: 6
    Last Post: 8th January 2007, 10:24

Tags for this Thread

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.