blob: 4cd870657bce78eb4f23f0b274464d1ac3f859a5 [file] [log] [blame]
Guido van Rossum50d5e8a1995-03-04 22:57:56 +00001# Send/receive UDP multicast packets.
2# Requires that your OS kernel supports IP multicast.
3# This is built-in on SGI, still optional for most other vendors.
4#
Guido van Rossum4fab6a51992-09-08 21:19:55 +00005# Usage:
6# mcast -s (sender)
Guido van Rossumc8833d41992-09-24 10:33:16 +00007# mcast -b (sender, using broadcast instead multicast)
Guido van Rossum4fab6a51992-09-08 21:19:55 +00008# mcast (receivers)
9
10MYPORT = 8123
Guido van Rossum7814c101992-09-24 10:33:40 +000011MYGROUP = '225.0.0.250'
Guido van Rossum4fab6a51992-09-08 21:19:55 +000012
13import sys
14import time
15import struct
Guido van Rossum7814c101992-09-24 10:33:40 +000016import regsub
Guido van Rossum4fab6a51992-09-08 21:19:55 +000017from socket import *
Guido van Rossum4fab6a51992-09-08 21:19:55 +000018
Guido van Rossum4fab6a51992-09-08 21:19:55 +000019
Guido van Rossumbd07b311992-11-16 16:54:45 +000020# Main program
21def main():
22 flags = sys.argv[1:]
23 #
24 if flags:
25 sender(flags[0])
26 else:
27 receiver()
Guido van Rossum4fab6a51992-09-08 21:19:55 +000028
Guido van Rossumbd07b311992-11-16 16:54:45 +000029
30# Sender subroutine (only one per local area network)
31def sender(flag):
32 s = socket(AF_INET, SOCK_DGRAM)
33 if flag == '-b':
Guido van Rossumc8833d41992-09-24 10:33:16 +000034 s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
35 mygroup = '<broadcast>'
36 else:
Guido van Rossum7814c101992-09-24 10:33:40 +000037 mygroup = MYGROUP
Guido van Rossumc8833d41992-09-24 10:33:16 +000038 ttl = struct.pack('b', 1) # Time-to-live
39 s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)
Guido van Rossum4fab6a51992-09-08 21:19:55 +000040 while 1:
Guido van Rossumc8833d41992-09-24 10:33:16 +000041 data = `time.time()`
42## data = data + (1400 - len(data)) * '\0'
Guido van Rossum4fab6a51992-09-08 21:19:55 +000043 s.sendto(data, (mygroup, MYPORT))
Guido van Rossumc8833d41992-09-24 10:33:16 +000044 time.sleep(1)
Guido van Rossum4fab6a51992-09-08 21:19:55 +000045
Guido van Rossuma1b51f31992-10-25 19:20:47 +000046
Guido van Rossumbd07b311992-11-16 16:54:45 +000047# Receiver subroutine (as many as you like)
48def receiver():
49 # Open and initialize the socket
50 s = openmcastsock(MYGROUP, MYPORT)
51 #
Guido van Rossum4fab6a51992-09-08 21:19:55 +000052 # Loop, printing any data we receive
53 while 1:
54 data, sender = s.recvfrom(1500)
55 while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
56 print sender, ':', `data`
Guido van Rossumbd07b311992-11-16 16:54:45 +000057
58
59# Open a UDP socket, bind it to a port and select a multicast group
60def openmcastsock(group, port):
61 # Import modules used only here
62 import regsub
Guido van Rossumbd07b311992-11-16 16:54:45 +000063 import struct
Guido van Rossumbd07b311992-11-16 16:54:45 +000064 #
65 # Create a socket
Guido van Rossum50d5e8a1995-03-04 22:57:56 +000066 s = socket(AF_INET, SOCK_DGRAM)
Guido van Rossumbd07b311992-11-16 16:54:45 +000067 #
68 # Allow multiple copies of this program on one machine
69 # (not strictly needed)
70 s.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
71 #
72 # Bind it to the port
Guido van Rossum00d59741994-10-08 19:13:48 +000073 s.bind(('', port))
Guido van Rossumbd07b311992-11-16 16:54:45 +000074 #
75 # Look up multicast group address in name server
76 # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format)
Guido van Rossum50d5e8a1995-03-04 22:57:56 +000077 group = gethostbyname(group)
Guido van Rossumbd07b311992-11-16 16:54:45 +000078 #
79 # Construct binary group address
80 bytes = eval(regsub.gsub('\.', ',', group))
81 grpaddr = 0
82 for byte in bytes: grpaddr = (grpaddr << 8) | byte
83 #
84 # Construct struct mreq from grpaddr and ifaddr
85 ifaddr = INADDR_ANY
86 mreq = struct.pack('ll', grpaddr, ifaddr)
87 #
88 # Add group membership
89 s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
90 #
91 return s
92
93
94main()