Linux – BeagleBone Black : Qt 5. 3 Unable to send datagrams in UDP

BeagleBone Black : Qt 5. 3 Unable to send datagrams in UDP… here is a solution to the problem.

BeagleBone Black : Qt 5. 3 Unable to send datagrams in UDP

I’m working on BeagleBone Black (running Debian Linux) and I’m trying to send some datagrams using Qt 5.3 to broadcast over UDP.

Here is my code :

#include <QCoreApplication>
#include <QUdpSocket>
#include <QDebug>

#include <sys/socket.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QUdpSocket socket;

socket.bind(QHostAddress::AnyIPv4, 1111);

int opt=1;
    setsockopt(socket.socketDescriptor(), SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int));

QByteArray d = QString("Hello, world!"). toLatin1();
    int r = socket.writeDatagram(d, QHostAddress::Broadcast, 1111);

qDebug() << r;
    qDebug() << socket.error();
    qDebug() << socket.errorString();

return a.exec();
}

Unfortunately it doesn’t work, the output of the program is:

-1

QAbstractSocket::NetworkError

“Unable to send a message”

So the writeDatagram primitive failed. When compiled for my desktop PC, the exact same code worked very well… So I’m assuming the code is fine and there might be something particularly relevant to BBB.

I also tried sending a datagram to a specific IP address (instead of broadcast), but it didn’t change: BBB doesn’t seem to be able to send UDP packets at all….

Any thoughts on this? Do I need to configure on BBB for it to work?

Update

I modified the code slightly to explicitly enable SO_BROADCAST on that socket and bind the socket to any IPv4 interface (just for testing) but it doesn’t work anyway….

Looking at the process strace (you can see it here) It seems that the Linux kernel cannot recognize 255.255.255.255 as a broadcast address and tell the network that it is unreachable….

Here is my network configuration… I feel good, but don’t correct me!

Solution

I can reproduce this issue on RHEL 6 running 2.6.32-431.20.3.el6.x86_64. Even if bind to 0.0.0.0 succeeds, subsequent writeDatagrams will fail. When you bind (bind) to a specific interface, everything works fine.

By the way, your network interface is not configured correctly, although I don’t see any difference in the behavior of the program for this reason alone. The broadcast address on eth0 should be 192.168.79.255, not 255.255.255.255.

#include <QCoreApplication>
#include <QUdpSocket>
#include <QNetworkInterface>
#include <QDebug>

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QUdpSocket socket;

QList<QHostAddress> ifAddrs = QNetworkInterface::allAddresses();
   qDebug() << ifAddrs;

QHostAddress ifAddr(QHostAddress::Any);
   foreach (QHostAddress ia, ifAddrs) {
      if (ia.protocol() == QAbstractSocket::IPv6Protocol) continue;
      if (ia.isInSubnet(QHostAddress::LocalHost, 8)) continue;
      ifAddr = ia;
      break;
   }
   if (false) ifAddr = QHostAddress::Any;  *** Change to if (true) to make the write fail.
   qDebug() << ifAddr;

if (!socket.bind(ifAddr, 1111)) {
      qDebug() << "bind failed" << socket.error();
   }

QByteArray d = QString("Hello, world!"). toLatin1();
   int r = socket.writeDatagram(d, QHostAddress::Broadcast, 1111);

qDebug() << r;
   if (r < 0) {
      qDebug() << socket.error();
      qDebug() << socket.errorString();
   }

return 0;
}

Related Problems and Solutions