QUdpSocket : "Unable to send message" to multicast address
-
Hello,
Based on this example for sending multicast udp datagram : https://doc.qt.io/qt-6/qtnetwork-multicastsender-example.html
I can't understand why does my app keep failing on sending a datagram to a multicast address.
Curiously, the "example" works pretty well on my computer for my own sending message's multicast adress.My OS is "Windows" and I have deactivated my firewall.
There is my code :
""" in 'main.cpp' """
#include <QCoreApplication>
#include <QTimer>
#include "udpClient.h"void process(QCoreApplication *app) {
QHostAddress multicast_addr = QHostAddress("239.0.0.12");
quint16 port = 53290;
UdpClient udp_client = UdpClient(QHostAddress::LocalHost);
udp_client.socket_emitter->bind(QHostAddress::LocalHost, 1234);
while (true) {
if (udp_client.socket_emitter->writeDatagram("HELLO", multicast_addr, port) == -1) {
qDebug() << "Failed on sending datagram to multicast group at " << multicast_addr << ":" << port << "\n" << udp_client.socket_emitter->errorString();
break;
}
}
app->quit();
return;
}int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer::singleShot(0, &a , &a {process(&a);});
return a.exec();
}""" in udpclient.h """
#ifndef UDPCLIENT_H
#define UDPCLIENT_H#include <QUdpSocket>
#include <QByteArray>class UdpClient : public QObject {
Q_OBJECT
public:
explicit UdpClient(QHostAddress addr, QObject *parent = nullptr);
~UdpClient();public:
QHostAddress addr = QHostAddress::Null;
QUdpSocket *socket_emitter = new QUdpSocket(this);
};#endif // UDPCLIENT_H
""" in udpclient.cpp """
#include "udpClient.h"
UdpClient::UdpClient(QHostAddress addr, QObject *parent) : QObject(parent) {
this->addr = addr;
}UdpClient::~UdpClient() {
}
-
@setos95
The usual way to diagnose is to compare how your code differs from the working example code, making changes to see what "breaks" it.I note that the example has the Qt event loop running when it calls
writeDatagram()
while yours does not. Is that an issue (I don't know)? -
@JonB
First, as you can see, the "void process()" is launched by a qtimer when qcoreapplication gets executed at the end of the "int main()". So the "writeDatagram()" function is called through a qt event loop.Moreover, I've tried to modify the "qt example" so that the "sendDatagram" function is executed throught a direct connection with the qpushbutton clicked signal (so not through a Qtimer). And this didn't affect the good work of the "qt example" program.
Finally, my program can send on a non multicast address (ex: localhost) but not on a multicast address.
-
@setos95 said in QUdpSocket : "Unable to send message" to multicast address:
So the "writeDatagram()" function is called through a qt event loop.
I missed that, I now see it is in
process()
which is called on a timer and the event loop is indeed running, my bad.However, you call
writeDatagram()
inside awhile (true)
loop, which does not exit unless/until it fails. Are you aware that during that time no events will be processed? I wondered whether that might affect the behaviour ofwriteDatagram()
, but perhaps not?Not that I know the answer to your issue, but it would help if you told us whether the
writeDatagram()
fails on very first call or whether it succeeds many times and then eventually fails? -
@JonB
Ok so, I have tested a few different tries :- remove the while(true) statement, so that only one write diagram is called before the app quit.
- do "1)" but adding a qSleep(5000) to prevent the app from quitting too quickly after the datagram is sent.
- do "2)" but calling writeDatagram() through a qtimer.
The 3 attempts failed. Still have "Unable to send message"
Again, the weird things is that my program works on sending a datagram to a non-multicast address. So the event seems having nothing to deal with this issue....
-
@setos95 Unless I am missing something obvious your sender tries to reach a multicast address through the loopback interface. That interface will not have a route to use and probably not allow multicast.
The example uses any interface including the one that carries the default route and allows multicast.
Here are the two interface on my Linux box:
~$ ip link show lo 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 ~$ ip link show wlp15s0 3: wlp15s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000 link/ether 08:8e:90:11:20:d3 brd ff:ff:ff:ff:ff:ff
-
@ChrisW67 Thank you for the reply but...
-
There is my interfaces states before AND after running the "example program" that actually works.
-
Where, in its code, the "example uses any interface including...".
Because I ran the "example" by disabling the "setSocketOption" line and replaced in the ipv4 socket bind "::AnyIPv4" with "::LocalHost" and it did not prevent the app from sending datagrams to the concerned broadcast address.
-