This is the following code example from Twisted for dealing with receiving of multicasts. I currently am listening to many groups with the same client and I want to be able to print out which group a certain datagram packet came from. I would think that this can be received from the address parameter of datagramReceived; however, this only gives me a tuple containing the local ip and port that a group is bound to, but not the address of the group itself.
Question: How can I print the multicast address from where a datagram originated from within the Twisted protocol/API?
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class MulticastPingClient(DatagramProtocol):
def startProtocol(self):
# Join the multicast address, so we can receive replies:
self.transport.joinGroup("228.0.0.5")
self.transport.joinGroup("229.0.2.11")
self.transport.joinGroup("221.3.3.3")
# Send to 228.0.0.5:8005 - all listeners on the multicast address
# (including us) will receive this message.
self.transport.write('Client: Ping', ("228.0.0.5", 8005))
def datagramReceived(self, datagram, address):
print "Datagram %s received from %s" % (repr(datagram), repr(address))
reactor.listenMulticast(8005, MulticastPingClient(), listenMultiple=True)
reactor.run()
Unfortunately the socket APIs Twisted wraps (via Python’s standard library) do not provide this information. I would recommend having a separate DatagramProtocol for each multicast group, and listening on different ports for each. Although someone could still send a UDP datagram directly to to that port and you wouldn’t be able to distinguish it from multicast.
I have a vague memory indicating that the recvmsg() API does provide the necessary information, though I lack the time to verify this. Twisted 12.1 has the beginning of a recvmsg() wrapper, so this may be a possible way to add this functionality to Twisted (or your code) with a bit more work.