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. Sending UDP packets with QUdpSocket returns "UnknownSocketError" randomly
Forum Updated to NodeBB v4.3 + New Features

Sending UDP packets with QUdpSocket returns "UnknownSocketError" randomly

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 620 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.
  • N Offline
    N Offline
    Nastaran
    wrote on last edited by
    #1

    I'm trying to read a binary file, slice it into packets and send them with UDP protocol using QUdpSocket. Reading a file and sending packets are performed in two concurrent threads. This is a simplified version of my code.

    In ReadWriteManager class I have this slot:

    void ReadWriteManager::requestDataFromFile() {
        static int cursor{};
    
        if (!flagData[cursor]) {
            inputFile.read(reinterpret_cast<char*>(buffer + cursor * readSize),
                           readSize * sizeof(uint8_t));
            
            flagData[cursor++] = true;
            if (cursor == nChunks) cursor= 0;
        } 
        else {
            qDebug() << "----- ! Frame Loss ! -----";
        }
        if (!stopped)
            QTimer::singleShot(1, this, SLOT(requestDataFromFile()));
    }
    

    In UDPSender:

    UDPSender::UDPSender(QObject *parent)
        : QObject(parent) {
    
        mSocket = new QUdpSocket(this);
        mSocket->setPauseMode(QUdpSocket::PauseMode::PauseNever);
        mSocket->connectToHost(QHostAddress("192.168.1.255"), 2000);
    }
    

    and I have this slot:

    void UDPSender::sendPackets() {
        int cursor{};
        while (!stopped) {
            if (flagData[cursor]) {
    
                for (int i{}; i < readSize / payloadLen; ++i) {
                    memcpy(packet.data() + 4,
                           buffer + cursor * readSize + i * payloadLen,
                           payloadLen * sizeof(uint8_t));
    
                    if (mSocket->write(packet.constData(), packet.size()) < packet.size())
                        qDebug() << mSocket->error() << ", " << mSocket->errorString();
                }
    
                flagData[cursor++] = false;
                if (cursor == nChunks) cursor= 0;
            }
        }
    }
    

    flagData and buffer arrays are shared between the two classes, and I'm kinda implementing my own mutex and circular buffer. nChunks = 512 , payloadLen = 1460 and readSize = a * payloadLen where a is an integer. I control the transmission rate with a.

    When I run the program, I randomly see QAbstractSocket::UnknownSocketError, "Unknown error" in the console and it happens rarely (compared to the bit rate) but it's still there and the higher the bit rate, the more often I see this error. Do you have any suggestions on what the causes could be and how I can fix this? Is there any constraint on payloadLen? And what is the maximum bit rate I can achieve with connected socket in QUdpSocket? I'm using Windows 10, Qt 5.14.1.

    JonBJ 1 Reply Last reply
    0
    • J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Nastaran said in Sending UDP packets with QUdpSocket returns "UnknownSocketError" randomly:

      while (!stopped) {

      first of, I would get rid of the endless while loop, see if that is the cause of the error.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      N 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        @Nastaran said in Sending UDP packets with QUdpSocket returns "UnknownSocketError" randomly:

        while (!stopped) {

        first of, I would get rid of the endless while loop, see if that is the cause of the error.

        N Offline
        N Offline
        Nastaran
        wrote on last edited by
        #3

        @J-Hilk This is not an endless loop. The code here is simplified. stopped will be set to true when I hit the stop button in GUI. And the compiler will not optimize it out. It is tested.

        J.HilkJ 1 Reply Last reply
        0
        • N Nastaran

          I'm trying to read a binary file, slice it into packets and send them with UDP protocol using QUdpSocket. Reading a file and sending packets are performed in two concurrent threads. This is a simplified version of my code.

          In ReadWriteManager class I have this slot:

          void ReadWriteManager::requestDataFromFile() {
              static int cursor{};
          
              if (!flagData[cursor]) {
                  inputFile.read(reinterpret_cast<char*>(buffer + cursor * readSize),
                                 readSize * sizeof(uint8_t));
                  
                  flagData[cursor++] = true;
                  if (cursor == nChunks) cursor= 0;
              } 
              else {
                  qDebug() << "----- ! Frame Loss ! -----";
              }
              if (!stopped)
                  QTimer::singleShot(1, this, SLOT(requestDataFromFile()));
          }
          

          In UDPSender:

          UDPSender::UDPSender(QObject *parent)
              : QObject(parent) {
          
              mSocket = new QUdpSocket(this);
              mSocket->setPauseMode(QUdpSocket::PauseMode::PauseNever);
              mSocket->connectToHost(QHostAddress("192.168.1.255"), 2000);
          }
          

          and I have this slot:

          void UDPSender::sendPackets() {
              int cursor{};
              while (!stopped) {
                  if (flagData[cursor]) {
          
                      for (int i{}; i < readSize / payloadLen; ++i) {
                          memcpy(packet.data() + 4,
                                 buffer + cursor * readSize + i * payloadLen,
                                 payloadLen * sizeof(uint8_t));
          
                          if (mSocket->write(packet.constData(), packet.size()) < packet.size())
                              qDebug() << mSocket->error() << ", " << mSocket->errorString();
                      }
          
                      flagData[cursor++] = false;
                      if (cursor == nChunks) cursor= 0;
                  }
              }
          }
          

          flagData and buffer arrays are shared between the two classes, and I'm kinda implementing my own mutex and circular buffer. nChunks = 512 , payloadLen = 1460 and readSize = a * payloadLen where a is an integer. I control the transmission rate with a.

          When I run the program, I randomly see QAbstractSocket::UnknownSocketError, "Unknown error" in the console and it happens rarely (compared to the bit rate) but it's still there and the higher the bit rate, the more often I see this error. Do you have any suggestions on what the causes could be and how I can fix this? Is there any constraint on payloadLen? And what is the maximum bit rate I can achieve with connected socket in QUdpSocket? I'm using Windows 10, Qt 5.14.1.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @Nastaran
          Apart from your problem and @J-Hilk's suggestion (which you should try).

          What are you trying to achieve here with UDP? Reliable file transfer?? Are you aware of the behaviour of UDP and the (lack of) reliability for your purpose? E.g. https://cs.stackexchange.com/questions/96159/does-udp-always-deliver-packets-inorder-to-the-application-layer

          Conversely from TCP, UDP does not guarantee a reliable or ordered delivery of the packets.

          As the RFC states:

          This protocol provides a procedure for application programs to send messages to other programs with a minimum of protocol mechanism. The protocol is transaction oriented, and delivery and duplicate protection are not guaranteed. Applications requiring ordered reliable delivery of streams of data should use the Transmission Control Protocol (TCP)

          No. While UDP does deliver packets reliably 98-99% of the time, without duplicating packets 99.9% of the time, and in-order 99.9% of the time, there is absolutely no guarantee for either of these (in fact you are expected to be prepared for all of these), and reality verifiably doesn't look 100% perfect all the time.

          Etc.

          N 1 Reply Last reply
          0
          • N Nastaran

            @J-Hilk This is not an endless loop. The code here is simplified. stopped will be set to true when I hit the stop button in GUI. And the compiler will not optimize it out. It is tested.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @Nastaran said in Sending UDP packets with QUdpSocket returns "UnknownSocketError" randomly:

            stopped will be set to true when I hit the stop button in GUI.

            that makes it for all sense and purpose an endless loop :P

            did you also "simplify out" calls to processEvent() ? Also a typical cause for unexplainable errors


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            0
            • JonBJ JonB

              @Nastaran
              Apart from your problem and @J-Hilk's suggestion (which you should try).

              What are you trying to achieve here with UDP? Reliable file transfer?? Are you aware of the behaviour of UDP and the (lack of) reliability for your purpose? E.g. https://cs.stackexchange.com/questions/96159/does-udp-always-deliver-packets-inorder-to-the-application-layer

              Conversely from TCP, UDP does not guarantee a reliable or ordered delivery of the packets.

              As the RFC states:

              This protocol provides a procedure for application programs to send messages to other programs with a minimum of protocol mechanism. The protocol is transaction oriented, and delivery and duplicate protection are not guaranteed. Applications requiring ordered reliable delivery of streams of data should use the Transmission Control Protocol (TCP)

              No. While UDP does deliver packets reliably 98-99% of the time, without duplicating packets 99.9% of the time, and in-order 99.9% of the time, there is absolutely no guarantee for either of these (in fact you are expected to be prepared for all of these), and reality verifiably doesn't look 100% perfect all the time.

              Etc.

              N Offline
              N Offline
              Nastaran
              wrote on last edited by
              #6

              @JonB Thank you for the link. Yes, that's what I expected. Even though UDP does not guarantee reliable delivery, I thought there should not be any packet loss since I'm sending packets from one computer to another using an Ethernet cable (wired connection, only two computers involved! ) but that's apparently not the case.

              JonBJ 1 Reply Last reply
              0
              • N Nastaran

                @JonB Thank you for the link. Yes, that's what I expected. Even though UDP does not guarantee reliable delivery, I thought there should not be any packet loss since I'm sending packets from one computer to another using an Ethernet cable (wired connection, only two computers involved! ) but that's apparently not the case.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @Nastaran
                Indeed, I wouldn't make your own assumption of how it might behave just because you have a physical direct connection!

                Even the Qt docs state:

                It can be used when reliability isn't important.

                If you are trying to use UDP because you think that's a faster way of transferring files you would not be the first person on this forum to think that is a good idea! There is a reason why file transfer programs use TCP and not UDP...!

                So if you move away from UDP this question becomes moot. If you insist on sticking with it I would start by:

                • Put a qDebug() immediately above & below the if (mSocket->write()). See if the intermittent error message does indeed come between these two outputs, so you know it is on that send line.

                • Put a slot on QAbstractSocket::errorOccurred() to see when that error is emitted.

                • You might also slot onto QIODevice::bytesWritten() to see how the data sent is being processed.

                1 Reply Last reply
                1

                • Login

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