I am trying to design a straightforward client/server pair for IPv6 multicast communication in Python. The code I have so far seems conforms to examples I've seen online, but my server never receives data.
I see the subscription in ip maddr show
and netstat -g
. tcpdump shows: 10:13:36.913546 IP6 (flowlabel 0x77fe8, hlim 5, next-header UDP (17) payload length: 20) **omitted** > ff16::fe.commplex-main: [udp sum ok] UDP, length 12
The client and server are connected to the same switch and the IPv6 unicast addresses are in the same subnet (they can ping eachother).
Server
#!/usr/bin/python3
import socket
import struct
local_addr = ::
mcast_addr = "ff16::fe"
mcast_port = 5000
ifn = "eno1"
# Create socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
# Set multicast interface
ifi = socket.if_nametoindex(ifn)
ifis = struct.pack("I", ifi)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifis)
# Set multicast group to join
group = socket.inet_pton(socket.AF_INET6, mcast_addr) + ifis
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock_addr = socket.getaddrinfo(local_addr, mcast_port, socket.AF_INET6, socket.SOCK_DGRAM)[0][4]
sock.bind(sock_addr)
cmd = ""
while True:
data, src = sock.recvfrom(1024)
print("From " + str(src) + ": " + data.decode())
Client
#!/usr/bin/python3
import socket
import struct
message = "Hello world!"
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock_addr = socket.getaddrinfo("ff16::fe", 5000, socket.AF_INET6, socket.SOCK_DGRAM)[0][4]
ttl = struct.pack('i', 5)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl)
sock.sendto(message.encode(), sock_addr)
Any input would be appreciated.
In addition to all the other good advice: you bind the socket on the server to the link local address. This will filter incoming packets so that only packets with that destination address reach your code. Packets addressed to the multicast address will be dropped. Try binding to :: and make sure that works before moving on to something more complex.