PDA

View Full Version : UDP socket doesn't receive packets



Cruz
21st May 2012, 16:47
Hello!

I'm having troubles receiving UDP broadcast packets to a low port (port number 1001) on a Windows machine.
I'm using Wireshark to check if the packets arrive on my host successfully and this is the case. Binding the
socket to the "any" address and the low port returns true. Nevertheless, I tried running my program with
administrator privileges and it doesn't change anything. The readyRead() signal is never emitted and when I
manually test for pendingDatagramSize() it always returns -1. Below is the code of my UDPSocket class, that
works perfectly fine in a different application, where a high port is used. Any ideas what I'm doing wrong?




UDPSocket::UDPSocket()
{
portNumber = 1001;
bool yes = udpSocket.bind(portNumber, QUdpSocket::ShareAddress); // bind returns true!
qDebug() << "udp socket bind says" << yes;
}

void UDPSocket::startRecording()
{
processPendingDatagrams(); // Clear the socket to make sure the readyRead() signal will be emitted.
data.clear();
connect(&udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
qDebug() << "udp socket is connected";
}

void UDPSocket::stopRecording()
{
udpSocket.disconnect(); // Disconnects the Qt signal, not the socket.
}

void UDPSocket::processPendingDatagrams()
{
QHostAddress sender;
quint16 senderPort;

qDebug() << "packet arrived!";

while (udpSocket.hasPendingDatagrams())
{
datagram.resize(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
data.append(datagram);
}
}

wysota
21st May 2012, 17:52
Check your firewall settings. Usually you shouldn't access ports lower than 1025.

Cruz
21st May 2012, 20:12
Oh I didn't think of that one! However, I turned off the firewall and it still doesn't work. :( In netstat I can see that that something is listening for UDP packets on 0.0.0.0:1001.

wysota
21st May 2012, 23:27
It doesn't mean it is going to be receiving those packets that are trying to arrive there. Why are you trying to use port 1001? You really shouldn't be doing that. Port 1001 is a standard port assigned to a service called "pmake customs server" (whatever that is).

Cruz
22nd May 2012, 01:11
I have to use port 1001 because the software the sends the packets is not changeable.
The problem was that it's not a broadcast stream, but a multicast stream. Thanks to Qt 4.8.1 this change is easy to make.

Cruz
23rd May 2012, 10:34
I have run into more trouble with assigning a network interface to a multicast group.
My host has more than one network interface (this is very common). It has a wireless interface and a cable LAN interface.
The interfaces have different IP addresses and since QUdpSocket::joinMulticastGroup(QHostAddress) (http://qt-project.org/doc/qt-4.8/qudpsocket.html#joinMulticastGroup) assigns
whichever network interface it seems fit to the desired multicast group, I want to explicitly assign the cable interface.
So here is what I do:



UDPSocket::UDPSocket()
{
udpSocket.bind(1001, QUdpSocket::ShareAddress);

// alternative 1:
udpSocket.setMulticastInterface(getNetworkInterfac eByAddress("10.7.7.140"));
udpSocket.joinMulticastGroup(QHostAddress("224.0.0.1"));

// alternative 2:
//udpSocket.joinMulticastGroup(QHostAddress("224.0.0.1"), getNetworkInterfaceByAddress("10.7.7.140"));

qDebug() << "Multicast group joined on interface:";
QNetworkInterface intf(udpSocket.multicastInterface());
printNetworkInterfaceInfo(intf);
}

QNetworkInterface UDPSocket::getNetworkInterfaceByAddress(QString adr)
{
QList<QNetworkInterface> il(QNetworkInterface::allInterfaces());
for (int i = 0; i < il.size(); i++)
{
QList<QNetworkAddressEntry> ade(il[i].addressEntries());
for (int j = 0; j < ade.size(); j++)
{
if (ade[j].ip().toString() == adr)
return il[i];
}
}

return QNetworkInterface();
}

void UDPSocket::printNetworkInterfaceInfo(QNetworkInter face ni)
{
qDebug() << ni.index() << ni.humanReadableName();
QList<QNetworkAddressEntry> ade(ni.addressEntries());
for (int j = 0; j < ade.size(); j++)
qDebug() << ade[j].ip();
}




The QUdpSocket provides two alternatives to assign a specific interface and both of them don't work for me.
The output of alternative 1 looks right though:



Multicast group joined on interface:
10 "Local Area Connection"
QHostAddress( "FE80::1544:8566:C8B3:A3B5" )
QHostAddress( "10.7.7.140" )


The output of alternative 2 is rubbish:



Multicast group joined on interface:
0 ""


In both cases I don't receive the multicast packets. Only when I completely disable the wireless interface such that the OS assigns the correct interface automatically it works and I receive the packets. Any comments on this?

bob2oneil
31st July 2018, 15:44
I had a similar experience all was well, where the readyRead() signal was not emitted unless I combined the interface with the joinMulticastGroup() method similar to the following example:



m_udpSocket = new(std::nothrow)QUdpSocket();

if (!m_udpSocket->bind(QHostAddress::AnyIPv4, UDP_DEST_PORT, QUdpSocket::ShareAddress))
{
qDebug() << "MainWindow::MainWindow:: Failed bind of multicast socket";
}

QNetworkInterface iface = getNetworkInterfaceByAddress("10.100.0.200");
if (!iface.isValid())
{
qDebug() << "MainWindow::MainWindow:: Multicast socket interface is invalid or does not exist";
}
else
{
m_udpSocket->setMulticastInterface(iface);

QHostAddress groupAddress4(QStringLiteral("224.1.2.8"));

// NOTE: must provide iface to the following join call or else readyRead() signal will not be emitted
if (!m_udpSocket->joinMulticastGroup(groupAddress4, iface))
{
qDebug() << "MainWindow::MainWindow:: Failed to join multicast group" << groupAddress4.toString() << "on interface" << iface.humanReadableName();
}
else
{
qDebug() << "MainWindow::MainWindow:: Successfully joined multicast group" << groupAddress4.toString() << "on interface" << m_udpSocket->multicastInterface();
printNetworkInterfaceInfo(iface);
}

auto fd = m_udpSocket->socketDescriptor();
if (fd != -1)
{
// Make connection for new data received
if (!connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())))
{
qDebug() << "MainWindow::MainWindow:: Failed to connect multicast socket readyRead() to handler";
}
else
{
qDebug() << "MainWindow::MainWindow:: Connected multicast socket readyRead() to handler";

#ifdef UDP_WRITE_TEST
QByteArray data("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S TAIL");
QNetworkDatagram datagram(data, groupAddress4, UDP_DEST_PORT);
m_udpSocket->writeDatagram(datagram);
#endif
}
}
else
{
qDebug("MainWindow::MainWindow:: Failed to obtain UDP socket descriptor, network sensing is not possible");
}
}