PDA

View Full Version : Qt5, receiving Multicast data, multiple interfaces and Network teaming on Centos 7.2



taraj
24th August 2017, 08:21
Hi,

I'm having trouble getting data into my Qt5 application. I am running Centos 7.2, Qt 5.6. I'm not sure if it is a Qt problem or a linux configuration problem, i believe I have almost exhausted my Linux troubleshooting so am looking at the Qt code as the possible problem.

The application listens for data on a multicast address on a team0 interface (I also have a eno1 interface for output of the data onto another LAN), when I join I am successful and get no errors returned, so I would expect to see data, but I don't.

This is what I have set up and tried:

I have a route-team0 set up in /etc/sysconfig/network-scripts/ as my application fails to join to the multicast addresses when this isn't specified.
I have a route-eno1 set up in /etc/sysconfig/network-scripts/ for my application to output data onto the eno1 interface, I can successfully output data on the correct interface from my application
teaming appears to be working correctly
tcpdump shows the incoming multicast data
when the application is running "ip maddr" shows the multicast address on the team0 interface
The value of sysctl rp_filter does not make a difference to the success as this is a common internet suggestion to fixing this problem.
I have this same application running on a machine with no team0 and just the one eno1 interface for input and output and it works perfectly.


Is there something additional in Qt for receiving (multicast) data from the correct interface when there are multiple interfaces? I see there is a call "udpSocket->setMulticastInterface(interface);" but this is documented as outgoing data (i did try it as was desperate but it didn't seem to make any difference)

Any ideas would be greatly appreciated as I have got as far as my brain will take me.

Thank you very much,
Tara

A snippet of the code for the udp socket with multicast



bool MyClass::Initialise()
{
udpSocket = new QUdpSocket(this);

struct servent *serv;
serv = getservbyname("multicast_in", "udp");

if(serv == NULL)
{
logging->write(LOG_ERR, QString("Cannot find service multicast_in in /etc/services."));
error = true;
}
else
{
quint16 port = qFromBigEndian(uint16_t(serv->s_port));

if(udpSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress) == true)
{
joinMulticastGroup(QString("mtrack"));
joinMulticastGroup(QString("strack"));
connect(udpSocket, SIGNAL(readyRead()),this, SLOT(dataReceived()), Qt::DirectConnection);

}
else
{
logging->write(LOG_ERR, QString("EFeed socket bind failed."));
error = true;
}
}
}

bool MyClass::joinMulticastGroup(QString group)
{
QHostAddress address;

bool error = false;

QHostInfo host = QHostInfo::fromName(group);

if(host.addresses().isEmpty())
{
logging->write(LOG_ERR, QString("EFeed address for %1 not found.").arg(group));
error = true;
}
else
{
address = host.addresses().first();

logging->write(LOG_INFO, QString("Joining multicast Group %1 Address %2").arg(group).arg(address.toString()));

if(udpSocket->joinMulticastGroup(address))
{
logging->write(LOG_INFO, QString("EFeed socket join multicast group %1 successful.").arg(group));
}
else
{
logging->write(LOG_ERR, QString("EFeed socket join multicast group %1 failed %2").arg(group).arg(udpSocket->errorString()));
error = true;
}
}

return error;
}
}