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. SocketError TemporaryError (22) during UDP discovery
Forum Updated to NodeBB v4.3 + New Features

SocketError TemporaryError (22) during UDP discovery

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 680 Views 2 Watching
  • 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.
  • R Offline
    R Offline
    riffraff
    wrote on last edited by
    #1

    Hello to everybody,
    I have developed a routine to discover UDP servers in the local network. The server is a program who answer "OK" when receiving the datagram "discovery".

    QStringList getDiscoveredIPAddressList(quint16 numPort)
    {
        QStringList iplist;
        QUdpSocket Client;
        const char* szDiscovery = "discovery";
        Client.writeDatagram(szDiscovery, QHostAddress::Broadcast, numPort);
        // Give time to all UDP servers to read request and answer
        QThread::msleep(50);
        while (true)
        {
            char recbuffer[32] = { 0, };
            quint16 numPortTemp;
            QHostAddress qHostTemp;
            int nReceived = Client.readDatagram(recbuffer, sizeof(recbuffer) - 1, &qHostTemp, &numPortTemp);
            QString strErr;
            if (nReceived <= 0)
            {
                // No more IP addresses to discover
                strErr.sprintf("Socket error: %d", Client.error());
                qDebug() << strErr;
                break;
            }
            QString thisIp = qHostTemp.toString();
            thisIp.replace("::ffff:", "");
            iplist << thisIp;
        }
    
        return iplist;
    }
    

    This function works perfectly when compiled in Windows.
    However, when compiled with g++ in a VMware Ubuntu linux guest machine, it doesn't discover any server. After calling the readDatagram() method, the program outputs the following error:

    "Socket error: 22"
    

    The error 22 is described as follow:
    A temporary error occurred (e.g., operation would block and socket is non-blocking).

    Additional information:

    1. It doesn't help to repeat many times the call to readDatagram(), or to increase the sleep time after the call of writeDatagram. The error 22 is repeatedly emitted after every call of readDatagram, and the readDatagram does never return any datagram.

    2. With Wireshark I have seen that the datagram is sent to the broadcast address and that all the available UDP servers send the answer to the IP address of the UDP client, exactly as they do when the UDP client is compiled in windows (and in this case, as said, the client receives these answers). So the problem is not in sending the discovery message, but in receiving the answer.

    3. I have written another program in which the UDP client sends / receives messages to / from a specific UDP server address, instead of broadcast, and in this case the communication works perfectly both in Ubuntu and in WIndows. The only difference between the broadcast case is that I use the connectToHost() before sending the request to the UDP server (but of course this cannot be the solution because I cannot use the connectToHost() to connect to the broadcast IP address)

    4. I developed a simple UDP discovery program in Ubuntu using the native linux socket functions (sendto, recvfrom etc.) and it works perfectly. This remark is just to say that it is not a network problem of the Ubuntu machine.

    After much googleing I could not find anyone who faced the same issue. I spent many hours to make several variant and try possible solutions and I honestly came to a dead end.

    What is wrong in my code? Is it possible to enable some tracing / diagnostic functionsality to understand where is the error?
    Any help would be greatly appreciated.

    Thank you in advance

    jsulmJ 1 Reply Last reply
    0
    • R riffraff

      Hello to everybody,
      I have developed a routine to discover UDP servers in the local network. The server is a program who answer "OK" when receiving the datagram "discovery".

      QStringList getDiscoveredIPAddressList(quint16 numPort)
      {
          QStringList iplist;
          QUdpSocket Client;
          const char* szDiscovery = "discovery";
          Client.writeDatagram(szDiscovery, QHostAddress::Broadcast, numPort);
          // Give time to all UDP servers to read request and answer
          QThread::msleep(50);
          while (true)
          {
              char recbuffer[32] = { 0, };
              quint16 numPortTemp;
              QHostAddress qHostTemp;
              int nReceived = Client.readDatagram(recbuffer, sizeof(recbuffer) - 1, &qHostTemp, &numPortTemp);
              QString strErr;
              if (nReceived <= 0)
              {
                  // No more IP addresses to discover
                  strErr.sprintf("Socket error: %d", Client.error());
                  qDebug() << strErr;
                  break;
              }
              QString thisIp = qHostTemp.toString();
              thisIp.replace("::ffff:", "");
              iplist << thisIp;
          }
      
          return iplist;
      }
      

      This function works perfectly when compiled in Windows.
      However, when compiled with g++ in a VMware Ubuntu linux guest machine, it doesn't discover any server. After calling the readDatagram() method, the program outputs the following error:

      "Socket error: 22"
      

      The error 22 is described as follow:
      A temporary error occurred (e.g., operation would block and socket is non-blocking).

      Additional information:

      1. It doesn't help to repeat many times the call to readDatagram(), or to increase the sleep time after the call of writeDatagram. The error 22 is repeatedly emitted after every call of readDatagram, and the readDatagram does never return any datagram.

      2. With Wireshark I have seen that the datagram is sent to the broadcast address and that all the available UDP servers send the answer to the IP address of the UDP client, exactly as they do when the UDP client is compiled in windows (and in this case, as said, the client receives these answers). So the problem is not in sending the discovery message, but in receiving the answer.

      3. I have written another program in which the UDP client sends / receives messages to / from a specific UDP server address, instead of broadcast, and in this case the communication works perfectly both in Ubuntu and in WIndows. The only difference between the broadcast case is that I use the connectToHost() before sending the request to the UDP server (but of course this cannot be the solution because I cannot use the connectToHost() to connect to the broadcast IP address)

      4. I developed a simple UDP discovery program in Ubuntu using the native linux socket functions (sendto, recvfrom etc.) and it works perfectly. This remark is just to say that it is not a network problem of the Ubuntu machine.

      After much googleing I could not find anyone who faced the same issue. I spent many hours to make several variant and try possible solutions and I honestly came to a dead end.

      What is wrong in my code? Is it possible to enable some tracing / diagnostic functionsality to understand where is the error?
      Any help would be greatly appreciated.

      Thank you in advance

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by jsulm
      #2

      @riffraff Instead of using a while loop you should use the assynchronous nature of Qt and connect a slot to QUdpSocket::readyRead signal where you can read.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      R 1 Reply Last reply
      0
      • jsulmJ jsulm

        @riffraff Instead of using a while loop you should use the assynchronous nature of Qt and connect a slot to QUdpSocket::readyRead signal where you can read.

        R Offline
        R Offline
        riffraff
        wrote on last edited by
        #3

        @jsulm
        this is one of the other attempts that I did, without success. The hook (slot) function was never called.
        Anyway, the point of my post is not to find an alternative implementation of this snippet, but to understand why it doesn't work on linux, while in windows it works. Any idea? Can you explain why I get error 22?

        1 Reply Last reply
        0
        • K Offline
          K Offline
          kuzulis
          Qt Champions 2020
          wrote on last edited by
          #4

          Use Client.waitFor{ReadyRead|BytesWritten} after {read|write}Datagram(). But it is wrong way, anyway.

          R 1 Reply Last reply
          0
          • K kuzulis

            Use Client.waitFor{ReadyRead|BytesWritten} after {read|write}Datagram(). But it is wrong way, anyway.

            R Offline
            R Offline
            riffraff
            wrote on last edited by
            #5

            @kuzulis
            Thank you for the suggestion, but unfortunately did not help.
            Update: I have opened the syslog viewer of Ubuntu and I have found this:

            Sep 25 20:28:01 ubuntu kernel: [18037.619107] [UFW BLOCK] IN=ens33 OUT= MAC=00:0c:29:a3:01:66:84:a9:3e:87:20:e1:08:00 SRC=10.10.20.12 DST=10.10.20.15 LEN=31 TOS=0x00 PREC=0x00 TTL=128 ID=9523 PROTO=UDP SPT=11000 DPT=41558 LEN=11
            

            The incoming connection was blocked by the UFW (uncomplicated firewall). So I have disabled it:

            sudo ufw disable
            

            Afterwards, this simple and uncomplicated function, even though wrong, works like a charm

            Pablo J. RoginaP 1 Reply Last reply
            0
            • R riffraff

              @kuzulis
              Thank you for the suggestion, but unfortunately did not help.
              Update: I have opened the syslog viewer of Ubuntu and I have found this:

              Sep 25 20:28:01 ubuntu kernel: [18037.619107] [UFW BLOCK] IN=ens33 OUT= MAC=00:0c:29:a3:01:66:84:a9:3e:87:20:e1:08:00 SRC=10.10.20.12 DST=10.10.20.15 LEN=31 TOS=0x00 PREC=0x00 TTL=128 ID=9523 PROTO=UDP SPT=11000 DPT=41558 LEN=11
              

              The incoming connection was blocked by the UFW (uncomplicated firewall). So I have disabled it:

              sudo ufw disable
              

              Afterwards, this simple and uncomplicated function, even though wrong, works like a charm

              Pablo J. RoginaP Offline
              Pablo J. RoginaP Offline
              Pablo J. Rogina
              wrote on last edited by
              #6

              @riffraff said in SocketError TemporaryError (22) during UDP discovery:

              works like a charm

              so please don't forget to mark your post as solved then!

              Upvote the answer(s) that helped you solve the issue
              Use "Topic Tools" button to mark your post as Solved
              Add screenshots via postimage.org
              Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0

              • Login

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