Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2b1a467

Browse files
committed
Merged revisions 72237 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r72237 | gregory.p.smith | 2009-05-03 11:42:15 -0700 (Sun, 03 May 2009) | 3 lines Issue 5379 - applies patch supplied by philipp hagemeister to fix many problems with the ancient mcast.py demo code. ........
1 parent 05bf1d2 commit 2b1a467

2 files changed

Lines changed: 65 additions & 78 deletions

File tree

Demo/sockets/README

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,10 @@ echosvr.py About the simplest TCP server possible.
55
finger.py Client for the 'finger' protocol.
66
ftp.py A very simple ftp client.
77
gopher.py A simple gopher client.
8+
mcast.py IPv4/v6 multicast example
89
radio.py Receive time broadcasts from broadcast.py.
910
telnet.py Client for the 'telnet' protocol.
1011
throughput.py Client and server to measure TCP throughput.
1112
unixclient.py Unix socket example, client side
1213
unixserver.py Unix socket example, server side
1314
udpecho.py Client and server for the UDP echo protocol.
14-
15-
The following file is only relevant on SGI machines (or other systems
16-
that support multicast):
17-
18-
mcast.py A Python translation of
19-
/usr/people/4Dgifts/examples/network/mcast.c
20-
(Note that IN.py is in ../../lib/sgi.)
21-

Demo/sockets/mcast.py

Lines changed: 64 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,87 @@
1+
#!/usr/bin/env python
2+
#
13
# Send/receive UDP multicast packets.
24
# Requires that your OS kernel supports IP multicast.
3-
# This is built-in on SGI, still optional for most other vendors.
45
#
56
# Usage:
6-
# mcast -s (sender)
7-
# mcast -b (sender, using broadcast instead multicast)
8-
# mcast (receivers)
7+
# mcast -s (sender, IPv4)
8+
# mcast -s -6 (sender, IPv6)
9+
# mcast (receivers, IPv4)
10+
# mcast -6 (receivers, IPv6)
911

1012
MYPORT = 8123
11-
MYGROUP = '225.0.0.250'
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
1216

13-
import sys
17+
import ipaddr
1418
import time
1519
import struct
16-
from socket import *
17-
20+
import socket
21+
import sys
1822

19-
# Main program
2023
def main():
21-
flags = sys.argv[1:]
22-
#
23-
if flags:
24-
sender(flags[0])
24+
group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4
25+
26+
if "-s" in sys.argv[1:]:
27+
sender(group)
28+
else:
29+
receiver(group)
30+
31+
def _sockfam(ip):
32+
"""Returns the family argument of socket.socket"""
33+
if ip.version == 4:
34+
return socket.AF_INET
35+
elif ip.version == 6:
36+
return socket.AF_INET6
2537
else:
26-
receiver()
38+
raise ValueError('IPv' + ip.version + ' is not supported')
39+
40+
def sender(group):
41+
group_ip = ipaddr.IP(group)
2742

43+
s = socket.socket(_sockfam(group_ip), socket.SOCK_DGRAM)
2844

29-
# Sender subroutine (only one per local area network)
30-
def sender(flag):
31-
s = socket(AF_INET, SOCK_DGRAM)
32-
if flag == '-b':
33-
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
34-
mygroup = '<broadcast>'
45+
# Set Time-to-live (optional)
46+
ttl_bin = struct.pack('@i', MYTTL)
47+
if group_ip.version == 4:
48+
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
3549
else:
36-
mygroup = MYGROUP
37-
ttl = struct.pack('b', 1) # Time-to-live
38-
s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)
39-
while 1:
40-
data = repr(time.time())
41-
## data = data + (1400 - len(data)) * '\0'
42-
s.sendto(data, (mygroup, MYPORT))
50+
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
51+
52+
while True:
53+
data = repr(time.time()).encode('utf-8') + b'\0'
54+
s.sendto(data, (group_ip.ip_ext_full, MYPORT))
4355
time.sleep(1)
4456

4557

46-
# Receiver subroutine (as many as you like)
47-
def receiver():
48-
# Open and initialize the socket
49-
s = openmcastsock(MYGROUP, MYPORT)
50-
#
51-
# Loop, printing any data we receive
52-
while 1:
53-
data, sender = s.recvfrom(1500)
54-
while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
55-
print(sender, ':', repr(data))
58+
def receiver(group):
59+
group_ip = ipaddr.IP(group)
5660

57-
58-
# Open a UDP socket, bind it to a port and select a multicast group
59-
def openmcastsock(group, port):
60-
# Import modules used only here
61-
import string
62-
import struct
63-
#
6461
# Create a socket
65-
s = socket(AF_INET, SOCK_DGRAM)
66-
#
62+
s = socket.socket(_sockfam(group_ip), socket.SOCK_DGRAM)
63+
6764
# Allow multiple copies of this program on one machine
6865
# (not strictly needed)
69-
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
70-
#
66+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
67+
7168
# Bind it to the port
72-
s.bind(('', port))
73-
#
74-
# Look up multicast group address in name server
75-
# (doesn't hurt if it is already in ddd.ddd.ddd.ddd format)
76-
group = gethostbyname(group)
77-
#
78-
# Construct binary group address
79-
bytes = list(map(int, string.split(group, ".")))
80-
grpaddr = 0
81-
for byte in bytes: grpaddr = (grpaddr << 8) | byte
82-
#
83-
# Construct struct mreq from grpaddr and ifaddr
84-
ifaddr = INADDR_ANY
85-
mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr))
86-
#
87-
# Add group membership
88-
s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
89-
#
90-
return s
91-
92-
93-
main()
69+
s.bind(('', MYPORT))
70+
71+
# Join group
72+
if group_ip.version == 4: # IPv4
73+
mreq = group_ip.packed + struct.pack('=I', socket.INADDR_ANY)
74+
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
75+
else:
76+
mreq = group_ip.packed + struct.pack('@I', 0)
77+
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
78+
79+
# Loop, printing any data we receive
80+
while True:
81+
data, sender = s.recvfrom(1500)
82+
while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
83+
print(str(sender) + ' ' + repr(data))
84+
85+
86+
if __name__ == '__main__':
87+
main()

0 commit comments

Comments
 (0)