QUdpSocket dosnt emit readyRead when packets are fragmented.
-
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.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.
-
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.
@Christian-Ehrlicher
I checked and there was no problem. -
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.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 7575outputs 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.
-
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 7575outputs 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.
@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. -
@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.@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=15000Clearly 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.