Home | History | Annotate | Download | only in sockets
      1 #!/usr/bin/env python

      2 #

      3 # Send/receive UDP multicast packets.

      4 # Requires that your OS kernel supports IP multicast.

      5 #

      6 # Usage:

      7 #   mcast -s (sender, IPv4)

      8 #   mcast -s -6 (sender, IPv6)

      9 #   mcast    (receivers, IPv4)

     10 #   mcast  -6  (receivers, IPv6)

     11 
     12 MYPORT = 8123
     13 MYGROUP_4 = '225.0.0.250'
     14 MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
     15 MYTTL = 1 # Increase to reach other networks

     16 
     17 import time
     18 import struct
     19 import socket
     20 import sys
     21 
     22 def main():
     23     group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4
     24 
     25     if "-s" in sys.argv[1:]:
     26         sender(group)
     27     else:
     28         receiver(group)
     29 
     30 
     31 def sender(group):
     32     addrinfo = socket.getaddrinfo(group, None)[0]
     33 
     34     s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
     35 
     36     # Set Time-to-live (optional)

     37     ttl_bin = struct.pack('@i', MYTTL)
     38     if addrinfo[0] == socket.AF_INET: # IPv4

     39         s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
     40     else:
     41         s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
     42 
     43     while True:
     44         data = repr(time.time())
     45         s.sendto(data + '\0', (addrinfo[4][0], MYPORT))
     46         time.sleep(1)
     47 
     48 
     49 def receiver(group):
     50     # Look up multicast group address in name server and find out IP version

     51     addrinfo = socket.getaddrinfo(group, None)[0]
     52 
     53     # Create a socket

     54     s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
     55 
     56     # Allow multiple copies of this program on one machine

     57     # (not strictly needed)

     58     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     59 
     60     # Bind it to the port

     61     s.bind(('', MYPORT))
     62 
     63     group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
     64     # Join group

     65     if addrinfo[0] == socket.AF_INET: # IPv4

     66         mreq = group_bin + struct.pack('=I', socket.INADDR_ANY)
     67         s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
     68     else:
     69         mreq = group_bin + struct.pack('@I', 0)
     70         s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
     71 
     72     # Loop, printing any data we receive

     73     while True:
     74         data, sender = s.recvfrom(1500)
     75         while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's

     76         print (str(sender) + '  ' + repr(data))
     77 
     78 
     79 if __name__ == '__main__':
     80     main()
     81