Morix Dev Morix Dev - 1 month ago 31
Linux Question

BeagleBone Black: Qt 5.3 fails to send datagrams in UDP

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

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();
}


Unluckily it does not work and the output of the program is:


-1

QAbstractSocket::NetworkError

"Unable to send a message"


So the
writeDatagram
primitive fails. The same exact code works perfectly fine when compiled for my desktop PC... So I am assuming that the code is good and probably there is something specifically related to BBB.

I also tried to send the datagram to a specific IP address (instead of broadcast) but it does not change: BBB seems to be not able to send UDP packets at all...

Any ideas about that? Is there something to be configured on BBB for letting this work?

* UPDATE *

I slightly modified the code for explicitly enabling SO_BROADCAST on that socket and to bind the socket to any IPv4 interface (just to test) but it does not work anyway...

Looking at process
strace
(you can see it here) it seems that the linux kernel fails to recognize 255.255.255.255 as the broadcast address and tells that the network is unreacheable...

Here is my network configuration... it seems good to me, but correct me it not!

Answer

I can reproduce this issue on RHEL 6 running 2.6.32-431.20.3.el6.x86_64. Even though a bind to 0.0.0.0 succeeds, the subsequent writeDatagram fails. Things work perfectly well when you bind to a particular interface.

As an aside, your network interface is not properly configured, even though I can't see any difference in the behavior of the program due to this alone. The broadcast address on your 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;
}