mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #!/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()
 | 
