summaryrefslogtreecommitdiffstats
path: root/Tools/demo/mcast.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/demo/mcast.py')
-rwxr-xr-xTools/demo/mcast.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/Tools/demo/mcast.py b/Tools/demo/mcast.py
new file mode 100755
index 0000000..6ce7c6d
--- /dev/null
+++ b/Tools/demo/mcast.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# Send/receive UDP multicast packets.
+# Requires that your OS kernel supports IP multicast.
+#
+# Usage:
+# mcast -s (sender, IPv4)
+# mcast -s -6 (sender, IPv6)
+# mcast (receivers, IPv4)
+# mcast -6 (receivers, IPv6)
+
+MYPORT = 8123
+MYGROUP_4 = '225.0.0.250'
+MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
+MYTTL = 1 # Increase to reach other networks
+
+import time
+import struct
+import socket
+import sys
+
+def main():
+ group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4
+
+ if "-s" in sys.argv[1:]:
+ sender(group)
+ else:
+ receiver(group)
+
+
+def sender(group):
+ addrinfo = socket.getaddrinfo(group, None)[0]
+
+ s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
+
+ # Set Time-to-live (optional)
+ ttl_bin = struct.pack('@i', MYTTL)
+ if addrinfo[0] == socket.AF_INET: # IPv4
+ s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
+ else:
+ s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
+
+ while True:
+ data = repr(time.time()).encode('utf-8') + b'\0'
+ s.sendto(data, (addrinfo[4][0], MYPORT))
+ time.sleep(1)
+
+
+def receiver(group):
+ # Look up multicast group address in name server and find out IP version
+ addrinfo = socket.getaddrinfo(group, None)[0]
+
+ # Create a socket
+ s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
+
+ # Allow multiple copies of this program on one machine
+ # (not strictly needed)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+ # Bind it to the port
+ s.bind(('', MYPORT))
+
+ group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
+ # Join group
+ if addrinfo[0] == socket.AF_INET: # IPv4
+ mreq = group_bin + struct.pack('=I', socket.INADDR_ANY)
+ s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
+ else:
+ mreq = group_bin + struct.pack('@I', 0)
+ s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
+
+ # Loop, printing any data we receive
+ while True:
+ data, sender = s.recvfrom(1500)
+ while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
+ print(str(sender) + ' ' + repr(data))
+
+
+if __name__ == '__main__':
+ main()