Skip to content

Instantly share code, notes, and snippets.

@Anniepoo
Created May 7, 2018 08:33
Show Gist options
  • Save Anniepoo/17892e199bf3407c06862e38ee74d0c3 to your computer and use it in GitHub Desktop.
Save Anniepoo/17892e199bf3407c06862e38ee74d0c3 to your computer and use it in GitHub Desktop.
# socket_multicast_sender.py
# https://pymotw.com/3/socket/multicast.html
#
# This was working
#
# in one terminal
#
# sudo tcpdump -A -i lo port 20005
#
# in a second terminal
#
# udp_broadcast_initialize(ip(192.168.254.255), ip(255,255,255,0)).
#
# listen(architrave(X), (writeln(X),X=42)).
#
# findall(X, broadcast_request(udp_subnet(architrave(X))), Xs).
#
# notice we get a single 42
#
# sudo tcpdump -A -i lo port 20005
#
# in a third terminal on same machine
#
# python udp_multicast_bidi.py
#
# note that it prints an unbound variable, this is from python
#
# It will hang for 30 seconds, use editline and repeat the findall above
# before it times out. You wil see it report it
import socket
import struct
import sys
message = b'\'$udp_request\'(architrave(X))'
# the IP addy must match exactly what is used in prolog udp_broadcast_initialize
# eg one can't be 192.168.254.47 and the other 127.0.0.1
multicast_group = ('192.168.254.47', 20005)
# Create the datagram socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set a timeout so the socket does not block
# indefinitely when trying to receive data.
sock.settimeout(30.4) # was 0.2
# Set the time-to-live for messages to 1 so they do not
# go past the local network segment.
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
try:
# Send data to the multicast group
# this gets picked up by the listen above
print('sending {!r}'.format(message))
sent = sock.sendto(message, multicast_group)
# Look for responses from all recipients
while True:
print('waiting to receive')
try:
(data, server) = sock.recvfrom(4096) # 16 is buffer size
except socket.timeout:
print('timed out, no more responses')
break
else:
print('received {!r} from {}'.format(
data, server))
finally:
print('closing socket')
sock.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment