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 dosnt emit readyRead when packets are fragmented.
Qt 6.11 is out! See what's new in the release blog

QUdpSocket dosnt emit readyRead when packets are fragmented.

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.1k 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.
  • DanimaD Offline
    DanimaD Offline
    Danima
    wrote on last edited by
    #1

    I send a packet with size=15000 in MCU to PC.
    my created QUdpSocket dosnt emit readyread. but when i fragment data manually (not in IP Level) by sending data in several small packet I receive readyread signal. where is the problem.

    Christian EhrlicherC C 2 Replies Last reply
    0
    • DanimaD Danima

      I send a packet with size=15000 in MCU to PC.
      my created QUdpSocket dosnt emit readyread. but when i fragment data manually (not in IP Level) by sending data in several small packet I receive readyread signal. where is the problem.

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      It for sure does emit readyRead() but somewhere on the wire one of the fragmented packet is lost so the udp packet can not be re-assembled. You can check with wireshark if all udp packets are coming in.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      DanimaD 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        It for sure does emit readyRead() but somewhere on the wire one of the fragmented packet is lost so the udp packet can not be re-assembled. You can check with wireshark if all udp packets are coming in.

        DanimaD Offline
        DanimaD Offline
        Danima
        wrote on last edited by
        #3

        @Christian-Ehrlicher
        I checked and there was no problem.

        1 Reply Last reply
        0
        • DanimaD Danima

          I send a packet with size=15000 in MCU to PC.
          my created QUdpSocket dosnt emit readyread. but when i fragment data manually (not in IP Level) by sending data in several small packet I receive readyread signal. where is the problem.

          C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #4

          You will receive readyRead() once for each reassembled UDP datagram received at the bound interface and port.
          This sample receiver:

          #include <QCoreApplication>
          #include <QObject>
          #include <QUdpSocket>
          #include <QNetworkDatagram>
          #include <QDebug>
          
          class Receiver: public QObject {
                  Q_OBJECT
          public:
                  Receiver(QObject *p = nullptr) : QObject(p), udpSocket(nullptr) {
                          initSocket();
                  }
                  ~Receiver() { }
          
                  void initSocket() {
                      udpSocket = new QUdpSocket(this);
                      udpSocket->bind(QHostAddress::Any, 7575);
          
                      connect(udpSocket, &QUdpSocket::readyRead,
                              this, &Receiver::readPendingDatagrams);
                  }
          
                  void readPendingDatagrams() {
                      while (udpSocket->hasPendingDatagrams()) {
                          QNetworkDatagram datagram = udpSocket->receiveDatagram();
                          qDebug() << "Received datagram:" 
                                 << "isNull()" << datagram.isNull() << ","
                                 << "isValid()" << datagram.isValid() << ","
                                 << "Size " << datagram.data().size() << ","
                                 << "Starts " << datagram.data().first(32) ;
                      }
                  }
          private:
                  QUdpSocket *udpSocket;
          };
          
          int main(int argc, char *argv[]) {
              QCoreApplication a(argc, argv);
              Receiver receiver;
              return a.exec();
          }
          
          #include "main.moc"
          

          when sent datagrams of various sizes over a link with MTU 1500:

          /tmp$ ls -l datagram_*
          -rw-rw-r-- 1 chrisw chrisw 15000 Feb 28 09:20 datagram_15000
          -rw-rw-r-- 1 chrisw chrisw  2048 Feb 28 09:10 datagram_2048
          -rw-rw-r-- 1 chrisw chrisw   512 Feb 28 09:08 datagram_512
          /tmp$ ip addr show wlp1s0
          3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
              link/ether 00:c2:c6:f2:4f:13 brd ff:ff:ff:ff:ff:ff
              inet 192.168.1.14/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp1s0
                 valid_lft 4843sec preferred_lft 4843sec
              inet6 fe80::b930:88ca:91c5:701e/64 scope link noprefixroute 
                 valid_lft forever preferred_lft forever
          /tmp$ cat datagram_512 | nc -n -q 1 -u 192.168.1.6 7575
          /tmp$ cat datagram_2048 | nc -n -q 1 -u 192.168.1.6 7575
          /tmp$ cat datagram_15000 | nc -n -q 1 -u 192.168.1.6 7575
          

          outputs this:

          $ ./receiver 
          Received datagram: isNull() false , isValid() true , Size  512 , Starts  "Lorem ipsum dolor sit amet, cons"
          Received datagram: isNull() false , isValid() true , Size  2048 , Starts  "Nulla facilisi. Nunc commodo, ni"
          Received datagram: isNull() false , isValid() true , Size  15000 , Starts  "Cras a pellentesque lectus. Pell"
          

          Tcpdump reports this for the same received traffic:

          $ sudo tcpdump -n udp port 7575
          tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
          listening on wlp15s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
          09:25:50.457103 IP 192.168.1.14.47191 > 192.168.1.6.7575: UDP, length 512
          09:25:53.612263 IP 192.168.1.14.56037 > 192.168.1.6.7575: UDP, length 2048
          09:25:56.495298 IP 192.168.1.14.47335 > 192.168.1.6.7575: UDP, length 15000
          
          • If, as @Christian-Ehrlicher points out, a fragment is lost at the link layer then a datagram cannot be reassembled and you will not receive a readyRead indication.
          • If the sender is setting the DF flag on the IPv4 packet containing the datagram then any packet larger then the link MTU will never make it out of the sending machine (or get stopped by an intermediate step with a smaller MTU).

          If neither of these apply then the problem is somewhere in your code.

          DanimaD 1 Reply Last reply
          1
          • C ChrisW67

            You will receive readyRead() once for each reassembled UDP datagram received at the bound interface and port.
            This sample receiver:

            #include <QCoreApplication>
            #include <QObject>
            #include <QUdpSocket>
            #include <QNetworkDatagram>
            #include <QDebug>
            
            class Receiver: public QObject {
                    Q_OBJECT
            public:
                    Receiver(QObject *p = nullptr) : QObject(p), udpSocket(nullptr) {
                            initSocket();
                    }
                    ~Receiver() { }
            
                    void initSocket() {
                        udpSocket = new QUdpSocket(this);
                        udpSocket->bind(QHostAddress::Any, 7575);
            
                        connect(udpSocket, &QUdpSocket::readyRead,
                                this, &Receiver::readPendingDatagrams);
                    }
            
                    void readPendingDatagrams() {
                        while (udpSocket->hasPendingDatagrams()) {
                            QNetworkDatagram datagram = udpSocket->receiveDatagram();
                            qDebug() << "Received datagram:" 
                                   << "isNull()" << datagram.isNull() << ","
                                   << "isValid()" << datagram.isValid() << ","
                                   << "Size " << datagram.data().size() << ","
                                   << "Starts " << datagram.data().first(32) ;
                        }
                    }
            private:
                    QUdpSocket *udpSocket;
            };
            
            int main(int argc, char *argv[]) {
                QCoreApplication a(argc, argv);
                Receiver receiver;
                return a.exec();
            }
            
            #include "main.moc"
            

            when sent datagrams of various sizes over a link with MTU 1500:

            /tmp$ ls -l datagram_*
            -rw-rw-r-- 1 chrisw chrisw 15000 Feb 28 09:20 datagram_15000
            -rw-rw-r-- 1 chrisw chrisw  2048 Feb 28 09:10 datagram_2048
            -rw-rw-r-- 1 chrisw chrisw   512 Feb 28 09:08 datagram_512
            /tmp$ ip addr show wlp1s0
            3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
                link/ether 00:c2:c6:f2:4f:13 brd ff:ff:ff:ff:ff:ff
                inet 192.168.1.14/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp1s0
                   valid_lft 4843sec preferred_lft 4843sec
                inet6 fe80::b930:88ca:91c5:701e/64 scope link noprefixroute 
                   valid_lft forever preferred_lft forever
            /tmp$ cat datagram_512 | nc -n -q 1 -u 192.168.1.6 7575
            /tmp$ cat datagram_2048 | nc -n -q 1 -u 192.168.1.6 7575
            /tmp$ cat datagram_15000 | nc -n -q 1 -u 192.168.1.6 7575
            

            outputs this:

            $ ./receiver 
            Received datagram: isNull() false , isValid() true , Size  512 , Starts  "Lorem ipsum dolor sit amet, cons"
            Received datagram: isNull() false , isValid() true , Size  2048 , Starts  "Nulla facilisi. Nunc commodo, ni"
            Received datagram: isNull() false , isValid() true , Size  15000 , Starts  "Cras a pellentesque lectus. Pell"
            

            Tcpdump reports this for the same received traffic:

            $ sudo tcpdump -n udp port 7575
            tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
            listening on wlp15s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
            09:25:50.457103 IP 192.168.1.14.47191 > 192.168.1.6.7575: UDP, length 512
            09:25:53.612263 IP 192.168.1.14.56037 > 192.168.1.6.7575: UDP, length 2048
            09:25:56.495298 IP 192.168.1.14.47335 > 192.168.1.6.7575: UDP, length 15000
            
            • If, as @Christian-Ehrlicher points out, a fragment is lost at the link layer then a datagram cannot be reassembled and you will not receive a readyRead indication.
            • If the sender is setting the DF flag on the IPv4 packet containing the datagram then any packet larger then the link MTU will never make it out of the sending machine (or get stopped by an intermediate step with a smaller MTU).

            If neither of these apply then the problem is somewhere in your code.

            DanimaD Offline
            DanimaD Offline
            Danima
            wrote on last edited by
            #5

            @ChrisW67
            I used your code and still no results.
            I test with wireshark there is not any packet lost or error in packets,The said flag is 2(more fragments) for the first packets and 0 for the last packet(there is no don't fragment flag in packets).
            Meanwhile, I run the code in Windows 10.
            Based on my searches in Google, many people have this problem and I did not find a solution for it.

            C 1 Reply Last reply
            0
            • DanimaD Danima

              @ChrisW67
              I used your code and still no results.
              I test with wireshark there is not any packet lost or error in packets,The said flag is 2(more fragments) for the first packets and 0 for the last packet(there is no don't fragment flag in packets).
              Meanwhile, I run the code in Windows 10.
              Based on my searches in Google, many people have this problem and I did not find a solution for it.

              C Offline
              C Offline
              ChrisW67
              wrote on last edited by ChrisW67
              #6

              @Danima I do not have a Windows 10 machine handy. However, that code on the same hardware and Windows 11 (Qt 6.6.0, MingW, Intel(R) Wi-Fi 6E AX210 interface) produces this for the same sender commands:

              00:14:46: Starting ...\build-udptest-Desktop_Qt_6_6_0_MinGW_64_bit-Debug\debug\udptest.exe...
              Received datagram: isNull() false , isValid() true , Size  512 , Starts  "i vitae sapien ultricies, pulvin"
              Received datagram: isNull() false , isValid() true , Size  2048 , Starts  "ortor pellentesque eros, vel con"
              Received datagram: isNull() false , isValid() true , Size  15000 , Starts  "\n\nLorem ipsum dolor sit amet, co"
              

              Wireshark sees this:

              No.	Time	Source	Destination	Protocol	Length	Info
              146	3.871228	192.168.1.14	192.168.1.6	UDP	554	46323 → 7575 Len=512
              300	7.767207	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=0, ID=c393) [Reassembled in #301]
              301	7.767337	192.168.1.14	192.168.1.6	UDP	610	51108 → 7575 Len=2048
              458	11.655466	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=0, ID=608f) [Reassembled in #468]
              459	11.655466	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=1480, ID=608f) [Reassembled in #468]
              460	11.658399	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=2960, ID=608f) [Reassembled in #468]
              461	11.658399	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=4440, ID=608f) [Reassembled in #468]
              462	11.660395	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=5920, ID=608f) [Reassembled in #468]
              463	11.660541	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=7400, ID=608f) [Reassembled in #468]
              464	11.663441	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=8880, ID=608f) [Reassembled in #468]
              465	11.663441	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=10360, ID=608f) [Reassembled in #468]
              466	11.664635	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=11840, ID=608f) [Reassembled in #468]
              467	11.664787	192.168.1.14	192.168.1.6	IPv4	1514	Fragmented IP protocol (proto=UDP 17, off=13320, ID=608f) [Reassembled in #468]
              468	11.665426	192.168.1.14	192.168.1.6	UDP	242	50516 → 7575 Len=15000
              

              Clearly it works, even on Windows!

              Try turning off any Windows firewall, anti-virus software.
              Try a different interface or different machine.
              Try updating all network drivers involved.
              Try turning on/off any network interface workload offloading.

              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