views:

2205

answers:

5

How do you send and receive UDP Multicast in Python? Is there a standard library to do so?

+2  A: 

Multicast traffic is no different than regular UDP except for the IP address. Take a look at the standard socket library. You may be able to find something that builds on socket and is easier to use.

Dan Goldstein
Right. But how about joining a group? I'd like to not roll my own group join management if possible.
A: 

There is always Twisted for anything networky.

Ali A
+2  A: 

Multicast sender that broadcasts to a multicast group:

#!/usr/bin/env python

import socket
import struct

def main():
  MCAST_GRP = '224.1.1.1'
  MCAST_PORT = 5007
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
  sock.sendto('Hello World!', (MCAST_GRP, MCAST_PORT))

if __name__ == '__main__':
  main()

Multicast receiver that reads from a multicast group and prints hex data to the console:

#!/usr/bin/env python

import socket
import binascii

def main():
  MCAST_GRP = '224.1.1.1' 
  MCAST_PORT = 5007
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  try:
    sock.seckopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  except AttributeError:
     pass
   sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) 
   sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)

   sock.bind(('', MCAST_PORT))
   host = socket.gethostbyname(socket.gethostname())
   sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(host))
   sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, 
                   socket.inet_aton(MCAST_GRP) + socket.inet_aton(host))

   while 1:
     try:
       data, addr = sock.recvfrom(1024)
     except socket.error, e:
       print 'Expection'
     hexdata = binascii.hexlify(data)
     print 'Data = %s' % hexdata

if __name__ == '__main__':
  main()
Niranjan Tulpule
I tried this, it did not work. In Wireshark I can see the transmit, but I don't see any IGMP join stuff and I don't receive anything.
tolomea
+3  A: 

This works for me:

Receive

import socket
import struct

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
  print sock.recv(10240)

Send

import socket

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.sendto("robot", (MCAST_GRP, MCAST_PORT))

It is based off the examples from http://wiki.python.org/moin/UdpCommunication which didn't work.

My system is... Linux 2.6.31-15-generic #50-Ubuntu SMP Tue Nov 10 14:54:29 UTC 2009 i686 GNU/Linux Python 2.6.4

tolomea
A: 

Have a look at py-multicast. Network module can check if an interface supports multicast (on Linux at least).

import multicast
from multicast import network

receiver = multicast.MulticastUDPReceiver ("eth0", "238.0.0.1", 1234 )
data = receiver.read()
receiver.close()

config = network.ifconfig()
print config['eth0'].addresses
# ['10.0.0.1']
print config['eth0'].multicast
#True - eth0 supports multicast
print config['eth0'].up
#True - eth0 is up

Perhaps problems with not seeing IGMP, were caused by an interface not supporting multicast?

wroniasty