Multicast sender is an external software, running on a host in same subnet and sending packets to 224.2.2.5:XXXX group, where XXXX is a fixed port number.
Client program, written by me, successfully joins group by using QUdpSocket (Qt5), but is unable to receive packets when run Linux (several Debian flavors, kernel 3.16 or 5.10, libc >2.4) only if socket is bound to 0.0.0.0
. If bound to IP of concrete interface, there is no datagram pending. IT's fine for test environment where is only one NI, but not fine for production where a dozen of networks are present.
Binding code
sock = new QUdpSocket(this);
bool result = sock->bind( host_addr, port_num,
QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
if(!result)
{
debugline("Binding port had failed");
}
result &= sock->joinMulticastGroup(group);
if(!result)
{
debugline("Joining group had failed");
}
Receive code
QHostAddress addr;
quint16 port_num;
qint64 nextSize = sock->pendingDatagramSize();
if(nextSize < 0) peturn;
bool gotData = false;
while ( nextSize > -1 )
{
auto res = sock->readDatagram(reinterpret_cast<char*>(inputBuffer),
DataFrame::MaximumFrameSize, &addr, &port_num);
If host_addr
is not "0.0.0.0"
, pending datagram size remains zero, while tcpdump sregisters incoming packets with TTL=1 and netstat shows open socket.
On linux, with multicast, in general, you will want to either
0.0.0.0
(any) address - This will cause the socket to receive multicast packets, as well as unicast packets to the same port (or multiple multicast addresses with the same port).In most multicast use cases, I prefer #1, but I have had #2 come up from time to time. If you want to control which interfaces a multicast packet can be received on, you will want the overload for joinMulticastGroup
which takes the network interface, and you will want to call it repeatedly.