Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QUdpSocket::hasPendingDatagrams() broken in Qt 5.5 on Windows Desktop

QUdpSocket::hasPendingDatagrams() broken in Qt 5.5 on Windows Desktop

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtnetworkqudpsocketwindows desktopqt5.5
3 Posts 1 Posters 3.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bsomervi
    wrote on 8 Nov 2015, 01:52 last edited by
    #1

    It seems that c86ca601edfde6e7b6a0769903d86bd48e26d70d has broken Qt 5.5 for our application. We are getting QIODevice::readReady() signals when we send datagrams on the socket and then calls to hasPendingDatagrams() return true and pendingDatagramSize() is returning zero. The problem is that we cannot ignore these "false" pending datagrams since that goes into a loop but if we try and read them then the readDatagram() triggers an error() signal due to the same WSAECONNRESET error.

    I believe this is because the writeDatagram is getting ICMP port unreachable because we are sending to the local host and no application is bound to the port (a valid scenario and not an error). WSARecvFrom documents that it will fail with WSAECONNRESET in these circumstances but that should not be interpreted as a pending datagram. Qt 5.4 worked as expected by consuming the "false" message in hasPendingDatagrams() and returning false.

    I believe that an empty datagram is valid so somehow QUdpSocket must differentiate between this error and a valid empty datagram.

    TIA
    Bill.

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bsomervi
      wrote on 8 Nov 2015, 13:16 last edited by
      #2

      Here is a test program that demonstrates the issue:

       #include <QCoreApplication>
       #include <QTimer>
       #include <QUdpSocket>
       #include <QHostAddress>
       #include <QByteArray>
       #include <QDebug>
       
       //
       // trivial UDP socket class that sends datagrams to a server and
       // processes any replies that may turn up
       //
       class MyUdpSocket final : public QUdpSocket
       {
         Q_OBJECT
       
       public:
         MyUdpSocket (QObject* parent = nullptr)
           : QUdpSocket {parent}
         {
           // report socket errors
           connect (this, static_cast<void (MyUdpSocket::*) (MyUdpSocket::SocketError)> (&MyUdpSocket::error)
                    , [this] (MyUdpSocket::SocketError const& err) {
                      qDebug () << "socket error:" << err << ":" << errorString ();
                    });
           connect (this, &MyUdpSocket::readyRead, this, &MyUdpSocket::get_reply);
       
           // bind to ephemeral port for any replies from server
           if (!bind ()) qDebug () << "bind failed";
       
           // send periodic datagrams to any server listening localhost:2237
           auto timer = new QTimer {this};
           connect (timer, &QTimer::timeout, [this]() {
               static const QByteArray ba {10, 'a'};
               auto bytes_sent = writeDatagram(ba, QHostAddress::LocalHost, 2237);
               qDebug () << "wrote" << bytes_sent << "byte datagram";
             });
           timer->start (2000);
         }
       
       private:
         // process replies from server
         Q_SLOT void get_reply ()
         {
           int i {0};
           while (hasPendingDatagrams ())
             {
               buffer_.resize (pendingDatagramSize ());
               QHostAddress sender;
               quint16 sender_port;
               auto size = readDatagram (buffer_.data (), buffer_.size (), &sender, &sender_port);
               qDebug() << ++i << "read" << size << "of"
                        << buffer_.size () << "bytesAvailable()" << bytesAvailable ();
             }
         }
       
         QByteArray buffer_;
       };
       
       int main (int argc, char * argv[])
       {
         QCoreApplication a {argc, argv};
         MyUdpSocket socket;
         return a.exec ();
       }
       
       
       #include "main.moc"
      

      and here is the output on Windows:

       main
       wrote 10 byte datagram
       socket error: QAbstractSocket::NetworkError : "Unable to receive a message"
       1 read -1 of 0 bytesAvailable() 0
       wrote 10 byte datagram
       socket error: QAbstractSocket::NetworkError : "Unable to receive a message"
       1 read -1 of 0 bytesAvailable() 0
       wrote 10 byte datagram
       socket error: QAbstractSocket::NetworkError : "Unable to receive a message"
       1 read -1 of 0 bytesAvailable() 0
       wrote 10 byte datagram
       socket error: QAbstractSocket::NetworkError : "Unable to receive a message"
       1 read -1 of 0 bytesAvailable() 0
       wrote 10 byte datagram
       socket error: QAbstractSocket::NetworkError : "Unable to receive a message"
       1 read -1 of 0 bytesAvailable() 0
      

      TIA
      Bill.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bsomervi
        wrote on 8 Nov 2015, 14:15 last edited by
        #3

        Raised issue https://bugreports.qt.io/browse/QTBUG-49301

        1 Reply Last reply
        0

        1/3

        8 Nov 2015, 01:52

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved