]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | #!/usr/bin/env python\r |
2 | #\r | |
3 | # Send/receive UDP multicast packets.\r | |
4 | # Requires that your OS kernel supports IP multicast.\r | |
5 | #\r | |
6 | # Usage:\r | |
7 | # mcast -s (sender, IPv4)\r | |
8 | # mcast -s -6 (sender, IPv6)\r | |
9 | # mcast (receivers, IPv4)\r | |
10 | # mcast -6 (receivers, IPv6)\r | |
11 | \r | |
12 | MYPORT = 8123\r | |
13 | MYGROUP_4 = '225.0.0.250'\r | |
14 | MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'\r | |
15 | MYTTL = 1 # Increase to reach other networks\r | |
16 | \r | |
17 | import time\r | |
18 | import struct\r | |
19 | import socket\r | |
20 | import sys\r | |
21 | \r | |
22 | def main():\r | |
23 | group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4\r | |
24 | \r | |
25 | if "-s" in sys.argv[1:]:\r | |
26 | sender(group)\r | |
27 | else:\r | |
28 | receiver(group)\r | |
29 | \r | |
30 | \r | |
31 | def sender(group):\r | |
32 | addrinfo = socket.getaddrinfo(group, None)[0]\r | |
33 | \r | |
34 | s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)\r | |
35 | \r | |
36 | # Set Time-to-live (optional)\r | |
37 | ttl_bin = struct.pack('@i', MYTTL)\r | |
38 | if addrinfo[0] == socket.AF_INET: # IPv4\r | |
39 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)\r | |
40 | else:\r | |
41 | s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)\r | |
42 | \r | |
43 | while True:\r | |
44 | data = repr(time.time())\r | |
45 | s.sendto(data + '\0', (addrinfo[4][0], MYPORT))\r | |
46 | time.sleep(1)\r | |
47 | \r | |
48 | \r | |
49 | def receiver(group):\r | |
50 | # Look up multicast group address in name server and find out IP version\r | |
51 | addrinfo = socket.getaddrinfo(group, None)[0]\r | |
52 | \r | |
53 | # Create a socket\r | |
54 | s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)\r | |
55 | \r | |
56 | # Allow multiple copies of this program on one machine\r | |
57 | # (not strictly needed)\r | |
58 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\r | |
59 | \r | |
60 | # Bind it to the port\r | |
61 | s.bind(('', MYPORT))\r | |
62 | \r | |
63 | group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])\r | |
64 | # Join group\r | |
65 | if addrinfo[0] == socket.AF_INET: # IPv4\r | |
66 | mreq = group_bin + struct.pack('=I', socket.INADDR_ANY)\r | |
67 | s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)\r | |
68 | else:\r | |
69 | mreq = group_bin + struct.pack('@I', 0)\r | |
70 | s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)\r | |
71 | \r | |
72 | # Loop, printing any data we receive\r | |
73 | while True:\r | |
74 | data, sender = s.recvfrom(1500)\r | |
75 | while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's\r | |
76 | print (str(sender) + ' ' + repr(data))\r | |
77 | \r | |
78 | \r | |
79 | if __name__ == '__main__':\r | |
80 | main()\r |