How to Udp Multicast in Python

not seeing UDP multicast messages from another device

As covered in https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html, the sockets API requires that you identify the interface as well as the multicast address/port you want to use.

By not specifying this in your sample code, you have left this down to the OS to pick and it has picked a VirtualBox Host-Only Network. Unfortunately this type of network is limited to VMs running on the Windows machines.

To fix it, you need to identify the interface that you want to use for the multicast and pass that in to your sending and receving code. For example:

sender.py

sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MCAST_IF_IP))
receiver.py

mreq = struct.pack('4s4s', group, socket.inet_aton(MCAST_IF_IP))

where MCAST_IF_IP is the IP address of the interface that you want to use.

Send and receive IPv6 link-local multicast UDP datagrams in Python?

Here's a link to python mcast demo, does both IPv4 and IPv6.

How to use the options to socket() for IPv6 multicast UDP?

Eventually figured this out. Here's the correct way of doing this:

import socket
import struct
import select
import ipaddress

# .packet is a byte array
mcast_group = ipaddress.IPv6Address("ff22:5eea:675c:d1fc:17c::1")
address = ipaddress.IPv6Address("...ipv6 global scope address of interface...")
port_no = 5555
interface_idx = 3

sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
group = struct.pack("16s i",
mcast_group.packed,
3 #Interface ID
)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock.bind((str(mcast_group), port_no, 0, interface_idx))

recv_socks, _, _ = select.select([sock], [], [], 10)
if recv_socks:
print("Received packet")

Important differences from the code in the question:

  • UDP (SOCK_DGRAM) sockets need to be bound to a port number. AFAICT this is why I was getting ICMP traffic as well as UDP with SOCK_RAW and no traffic at all with SOCK_DGRAM.
  • Instead of binding the socket to a unicast address on the interface of interest, bind it to the multicast group but use the interface index as the scope_id (the fourth in the address tuple passed to socket.bind()).

How can I get my server to UDP multicast to clients across the internet? Do I need a special multicast IP address?

You can't multicast on the Internet. Full stop.

Basically, multicast is only designed to work when there's someone in charge of the whole network to set it up. As you noted, that person needs to assign the multicast IP addresses, for example.

Use UDP without specifc port for Multicast

This isn't possible using the BSD socket API (which is roughly the API Python exposes in its socket module) - except by creating 2 ** 16 - 1 sockets and using them to bind to all ports.

It's possible using lower-level interfaces such as the TUN/TAP system offered by Linux.



Related Topics



Leave a reply



Submit