summaryrefslogtreecommitdiffstats
path: root/Demo/sockets/mcast.py
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2009-05-03 18:42:15 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2009-05-03 18:42:15 (GMT)
commit6493d788f0e6b96cd7d2ed70e8e39f8b8b7ec8d8 (patch)
tree9d0a250707d6b91df1b3aac3953bab67aa4ccc32 /Demo/sockets/mcast.py
parent62e9a653b5d61536ab397573ba5133ddcca80f26 (diff)
downloadcpython-6493d788f0e6b96cd7d2ed70e8e39f8b8b7ec8d8.zip
cpython-6493d788f0e6b96cd7d2ed70e8e39f8b8b7ec8d8.tar.gz
cpython-6493d788f0e6b96cd7d2ed70e8e39f8b8b7ec8d8.tar.bz2
Issue 5379 - applies patch supplied by philipp hagemeister to fix
many problems with the ancient mcast.py demo code.
Diffstat (limited to 'Demo/sockets/mcast.py')
-rwxr-xr-xDemo/sockets/mcast.py132
1 files changed, 63 insertions, 69 deletions
diff --git a/Demo/sockets/mcast.py b/Demo/sockets/mcast.py
index 1abd305..25fde79 100755
--- a/Demo/sockets/mcast.py
+++ b/Demo/sockets/mcast.py
@@ -1,93 +1,87 @@
+#!/usr/bin/env python
+#
# Send/receive UDP multicast packets.
# Requires that your OS kernel supports IP multicast.
-# This is built-in on SGI, still optional for most other vendors.
#
# Usage:
-# mcast -s (sender)
-# mcast -b (sender, using broadcast instead multicast)
-# mcast (receivers)
+# mcast -s (sender, IPv4)
+# mcast -s -6 (sender, IPv6)
+# mcast (receivers, IPv4)
+# mcast -6 (receivers, IPv6)
MYPORT = 8123
-MYGROUP = '225.0.0.250'
+MYGROUP_4 = '225.0.0.250'
+MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
+MYTTL = 1 # Increase to reach other networks
-import sys
+import ipaddr
import time
import struct
-from socket import *
-
+import socket
+import sys
-# Main program
def main():
- flags = sys.argv[1:]
- #
- if flags:
- sender(flags[0])
+ group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4
+
+ if "-s" in sys.argv[1:]:
+ sender(group)
+ else:
+ receiver(group)
+
+def _sockfam(ip):
+ """Returns the family argument of socket.socket"""
+ if ip.version == 4:
+ return socket.AF_INET
+ elif ip.version == 6:
+ return socket.AF_INET6
else:
- receiver()
+ raise ValueError('IPv' + ip.version + ' is not supported')
+
+def sender(group):
+ group_ip = ipaddr.IP(group)
+ s = socket.socket(_sockfam(group_ip), socket.SOCK_DGRAM)
-# Sender subroutine (only one per local area network)
-def sender(flag):
- s = socket(AF_INET, SOCK_DGRAM)
- if flag == '-b':
- s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
- mygroup = '<broadcast>'
+ # Set Time-to-live (optional)
+ ttl_bin = struct.pack('@i', MYTTL)
+ if group_ip.version == 4:
+ s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
else:
- mygroup = MYGROUP
- ttl = struct.pack('b', 1) # Time-to-live
- s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)
- while 1:
+ s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
+
+ while True:
data = repr(time.time())
-## data = data + (1400 - len(data)) * '\0'
- s.sendto(data, (mygroup, MYPORT))
+ s.sendto(data + '\0', (group_ip.ip_ext_full, MYPORT))
time.sleep(1)
-# Receiver subroutine (as many as you like)
-def receiver():
- # Open and initialize the socket
- s = openmcastsock(MYGROUP, MYPORT)
- #
- # Loop, printing any data we receive
- while 1:
- data, sender = s.recvfrom(1500)
- while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
- print sender, ':', repr(data)
+def receiver(group):
+ group_ip = ipaddr.IP(group)
-
-# Open a UDP socket, bind it to a port and select a multicast group
-def openmcastsock(group, port):
- # Import modules used only here
- import string
- import struct
- #
# Create a socket
- s = socket(AF_INET, SOCK_DGRAM)
- #
+ s = socket.socket(_sockfam(group_ip), socket.SOCK_DGRAM)
+
# Allow multiple copies of this program on one machine
# (not strictly needed)
- s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- #
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
# Bind it to the port
- s.bind(('', port))
- #
- # Look up multicast group address in name server
- # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format)
- group = gethostbyname(group)
- #
- # Construct binary group address
- bytes = map(int, string.split(group, "."))
- grpaddr = 0
- for byte in bytes: grpaddr = (grpaddr << 8) | byte
- #
- # Construct struct mreq from grpaddr and ifaddr
- ifaddr = INADDR_ANY
- mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr))
- #
- # Add group membership
- s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
- #
- return s
-
-
-main()
+ s.bind(('', MYPORT))
+
+ # Join group
+ if group_ip.version == 4: # IPv4
+ mreq = group_ip.packed + struct.pack('=I', socket.INADDR_ANY)
+ s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
+ else:
+ mreq = group_ip.packed + 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()