Last active
August 19, 2025 18:31
-
-
Save todbot/375e539740cfb790e8c6296ca423ebfe to your computer and use it in GitHub Desktop.
CircuitPython and desktop Python (CPython) multicast sender & receiver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import wifi | |
import socketpool | |
import ipaddress | |
import time, os | |
ssid = os.getenv("CIRCUITPY_WIFI_SSID") | |
password = os.getenv("CIRCUITPY_WIFI_PASSWORD") | |
HOST = "224.0.0.1" # multicast LAN address | |
PORT = 5000 | |
TIMEOUT = None | |
MAXBUF = 256 | |
print("Connecting to Wifi", ssid) | |
wifi.radio.connect(ssid, password) | |
pool = socketpool.SocketPool(wifi.radio) | |
print("Self IP", wifi.radio.ipv4_address) | |
server_ipv4 = ipaddress.ip_address(pool.getaddrinfo(HOST, PORT)[0][4][0]) | |
print("Server", server_ipv4, "port", PORT) | |
s = pool.socket(pool.AF_INET, pool.SOCK_DGRAM) | |
# currently undocumented: same as sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) | |
IPPROTO_IP = 0 | |
IP_MULTICAST_TTL = 5 | |
ttl = 2 | |
s.setsockopt( IPPROTO_IP, IP_MULTICAST_TTL, ttl) | |
s.settimeout(TIMEOUT) | |
s.bind((HOST, PORT)) | |
buf = bytearray(MAXBUF) | |
while True: | |
size, addr = s.recvfrom_into(buf) | |
print("Received", buf[:size], size, "bytes from", addr) | |
#size = s.sendto(buf[:size], addr) | |
#print("Sent", buf[:size], size, "bytes to", addr) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# invoke like: python3 ./udp-multicast-receiver 224.0.0.1 5000 | |
# can have multi receivers on different computers on the same LAN and they all receive the messages | |
import time, socket, sys | |
if len(sys.argv) < 2 or len(sys.argv) > 3: | |
print("udp-multicast-receiver.py <host> <port>") | |
exit(0) | |
udp_host = sys.argv[1] | |
udp_port = int(sys.argv[2]) | |
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP | |
ttl = 2 | |
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) | |
sock.bind((udp_host,udp_port)) | |
print("waiting for packets on",udp_host,udp_port) | |
while True: | |
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes | |
print("received message: %s" % data) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# invoke like: python3 ./udp-multicast-sender 224.0.0.1 5000 "hey buddy" | |
# can have multiple senders on different computers on the same LAN all sending to the multiple receivers | |
import time, socket, sys | |
if len(sys.argv) < 3 or len(sys.argv) > 4: | |
print("udp-multicast-sender.py <host> <port> [msg]") | |
exit(0) | |
udp_host = sys.argv[1] | |
udp_port = int(sys.argv[2]) | |
message = "hi there!" | |
if sys.argv == 4: | |
message = argv[3] | |
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP | |
ttl = 2 | |
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) | |
num = 0 | |
while True: | |
udp_message = bytes( f"{message} {num}", 'utf-8') | |
num += 1 | |
print(time.monotonic(), f"sending to {udp_host}:{udp_port} message:", udp_message) | |
sock.sendto(udp_message, (udp_host,udp_port) ) | |
time.sleep(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment