6
votes

I'm making an application where there is a certain thread (MulticastListenerThread) which has a MulticastSocket and is listening for UDP (datagram) packets sent to the multicast group the socket is listening too.

This works. I can join a multicast group, send a message to that group and receive it through the MulticastSocket.

However, I would like to determine, from the receiver point of view, from which multicast group he received the packet. The following code gives me the address of the originator of the packet, not the multicast group:

DatagramPacket packet = new DatagramPacket(buf, buf.length);
mlcSenderSocket.receive(packet);
String src_addr = packet.getAddress().getHostAddress();

The code for sending the packet is as follows:

InetAddress address = InetAddress.getByName(dest);
packet = new DatagramPacket(payload, payload.length,
    address, mlcEventPort);
LLog.out(this,"[NC] MLC packet Sent to ev port MLC " + mlcEventPort
    + " and to addr " + address);
mlcSenderSocket.send(packet);

Is it at all possible to determine which group sent the packet?

Edit:

It appears this isn't possible. In terms of performance impact (I'm working for IoT devices), would assigning a socket per multicast group (and hence, a listener thread per group) be viable? Potentially many groups may be joined (in terms of tens or hundreds even). If it is viable, then I just need to keep the joined group address somewhere manually and refer to it as necessary. Suggestions for other work arounds are welcome!

2
I suppose a work-around would be to maintain multiple MulticastSocket objects, one for each group you wish to join. It would then be easy enough to keep track of the association between sockets and groups. - Duncan Jones
I did think of that but it does seem overly excessive, especially since I there could be potentially many groups to join and this is (in theory) meant for constrained IoT devices. I'd then be required to have a listener thread per MulticastSocket, something I'd prefer not to do. - user4346741

2 Answers

2
votes

No group sent the packet. A socket at a specific IP address sent the packet, and the source IP address is available in the DatagramPacket. Multicast packets aren't sourced from multicast groups, they are addressed to multicast groups.

0
votes

Yes it's true that you can join a MulticastSocket to multiple groups, for example:

InetAddress group;

MulticastSocket s=new MulticastSocket(12345);
NetworkInterface ni=NetworkInterface.getByName("eth1");

group=InetAddress.getByName("239.255.10.10");
s.joinGroup(new InetSocketAddress(group,12345),ni);

group=InetAddress.getByName("239.255.10.11");
s.joinGroup(new InetSocketAddress(group,12345),ni);

You then receive datagrams like this:

DatagramPacket datagram=s.receive(datagram);

Unfortunately there is no java API call in the DatagramPacket object that will allow you to determine which of the two groups was targetted by the sender, all you can get is the IP address of the network interface on which it was received (from the socket) and the sender's IP address (from the datagram).

To achieve what you want to do you're going to need to create multiple MulticastSocket objects and listen to one group per socket. You could use your own threads or NIO to listen on them all simultaneously.