[sockets] What does it mean to bind a multicast (UDP) socket?

I am using multicast UDP between hosts that have multiple network interfaces. I am using boost::asio, and am confused by the 2 operations receivers have to make: bind, then join-group.

Why do you need to specify the local address of an interface, during bind, when you do that with every multicast group that you join?

The sister-question regards the multicast port: Since during sending, you send to a multicast address & port, why, during subscription to a multicast group, you only specify the address, not the port - the port being specified in the confusing call to bind.

Note: the "join-group" is a wrapper over setsockopt(IP_ADD_MEMBERSHIP), which as documented, may be called multiple times on the same socket to subscribe to different groups (over different networks?). It would therefore make perfect sense to ditch the bind call and specify the port every time I subscribe to a group.

From what I see, always binding to "0.0.0.0" and specifying the interface address when joining the group, works very well. Confused.

This question is related to sockets udp bind boost-asio multicast

The answer is


Correction for What does it mean to bind a multicast (udp) socket? as long as it partially true at the following quote:

The "bind" operation is basically saying, "use this local UDP port for sending and receiving data. In other words, it allocates that UDP port for exclusive use for your application

There is one exception. Multiple applications can share the same port for listening (usually it has practical value for multicast datagrams), if the SO_REUSEADDR option applied. For example

int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create UDP socket somehow
...
int set_option_on = 1;
// it is important to do "reuse address" before bind, not after
int res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &set_option_on, 
    sizeof(set_option_on));
res = bind(sock, src_addr, len);

If several processes did such "reuse binding", then every UDP datagram received on that shared port will be delivered to each of the processes (providing natural joint with multicasts traffic).

Here are further details regarding what happens in a few cases:

  1. attempt of any bind ("exclusive" or "reuse") to free port will be successful

  2. attempt to "exclusive binding" will fail if the port is already "reuse-binded"

  3. attempt to "reuse binding" will fail if some process keeps "exclusive binding"


It is also very important to distinguish a SENDING multicast socket from a RECEIVING multicast socket.

I agree with all the answers above regarding RECEIVING multicast sockets. The OP noted that binding a RECEIVING socket to an interface did not help. However, it is necessary to bind a multicast SENDING socket to an interface.

For a SENDING multicast socket on a multi-homed server, it is very important to create a separate socket for each interface you want to send to. A bound SENDING socket should be created for each interface.

  // This is a fix for that bug that causes Servers to pop offline/online.
  // Servers will intermittently pop offline/online for 10 seconds or so.
  // The bug only happens if the machine had a DHCP gateway, and the gateway is no longer accessible.
  // After several minutes, the route to the DHCP gateway may timeout, at which
  // point the pingponging stops.
  // You need 3 machines, Client machine, server A, and server B
  // Client has both ethernets connected, and both ethernets receiving CITP pings (machine A pinging to en0, machine B pinging to en1)
  // Now turn off the ping from machine B (en1), but leave the network connected.
  // You will notice that the machine transmitting on the interface with
  // the DHCP gateway will fail sendto() with errno 'No route to host'
  if ( theErr == 0 )
  {
     // inspired by 'ping -b' option in man page:      
     //      -b boundif
     //             Bind the socket to interface boundif for sending.
     struct sockaddr_in bindInterfaceAddr;
     bzero(&bindInterfaceAddr, sizeof(bindInterfaceAddr));
     bindInterfaceAddr.sin_len = sizeof(bindInterfaceAddr);
     bindInterfaceAddr.sin_family = AF_INET;
     bindInterfaceAddr.sin_addr.s_addr = htonl(interfaceipaddr);
     bindInterfaceAddr.sin_port = 0; // Allow the kernel to choose a random port number by passing in 0 for the port.
     theErr = bind(mSendSocketID, (struct sockaddr *)&bindInterfaceAddr, sizeof(bindInterfaceAddr));
     struct sockaddr_in serverAddress;
     int namelen = sizeof(serverAddress);  
     if (getsockname(mSendSocketID, (struct sockaddr *)&serverAddress, (socklen_t *)&namelen) < 0) {
        DLogErr(@"ERROR Publishing service... getsockname err");
     }
     else
     {
        DLog( @"socket %d bind, %@ port %d", mSendSocketID, [NSString stringFromIPAddress:htonl(serverAddress.sin_addr.s_addr)], htons(serverAddress.sin_port) );
     }

Without this fix, multicast sending will intermittently get sendto() errno 'No route to host'. If anyone can shed light on why unplugging a DHCP gateway causes Mac OS X multicast SENDING sockets to get confused, I would love to hear it.


The "bind" operation is basically saying, "use this local UDP port for sending and receiving data. In other words, it allocates that UDP port for exclusive use for your application. (Same holds true for TCP sockets).

When you bind to "0.0.0.0" (INADDR_ANY), you are basically telling the TCP/IP layer to use all available adapters for listening and to choose the best adapter for sending. This is standard practice for most socket code. The only time you wouldn't specify 0 for the IP address is when you want to send/receive on a specific network adapter.

Similarly if you specify a port value of 0 during bind, the OS will assign a randomly available port number for that socket. So I would expect for UDP multicast, you bind to INADDR_ANY on a specific port number where multicast traffic is expected to be sent to.

The "join multicast group" operation (IP_ADD_MEMBERSHIP) is needed because it basically tells your network adapter to listen not only for ethernet frames where the destination MAC address is your own, it also tells the ethernet adapter (NIC) to listen for IP multicast traffic as well for the corresponding multicast ethernet address. Each multicast IP maps to a multicast ethernet address. When you use a socket to send to a specific multicast IP, the destination MAC address on the ethernet frame is set to the corresponding multicast MAC address for the multicast IP. When you join a multicast group, you are configuring the NIC to listen for traffic sent to that same MAC address (in addition to its own).

Without the hardware support, multicast wouldn't be any more efficient than plain broadcast IP messages. The join operation also tells your router/gateway to forward multicast traffic from other networks. (Anyone remember MBONE?)

If you join a multicast group, all the multicast traffic for all ports on that IP address will be received by the NIC. Only the traffic destined for your binded listening port will get passed up the TCP/IP stack to your app. In regards to why ports are specified during a multicast subscription - it's because multicast IP is just that - IP only. "ports" are a property of the upper protocols (UDP and TCP).

You can read more about how multicast IP addresses map to multicast ethernet addresses at various sites. The Wikipedia article is about as good as it gets:

The IANA owns the OUI MAC address 01:00:5e, therefore multicast packets are delivered by using the Ethernet MAC address range 01:00:5e:00:00:00 - 01:00:5e:7f:ff:ff. This is 23 bits of available address space. The first octet (01) includes the broadcast/multicast bit. The lower 23 bits of the 28-bit multicast IP address are mapped into the 23 bits of available Ethernet address space.


Examples related to sockets

JS file gets a net::ERR_ABORTED 404 (Not Found) mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 TypeError: a bytes-like object is required, not 'str' Failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED No connection could be made because the target machine actively refused it 127.0.0.1 Sending a file over TCP sockets in Python socket connect() vs bind() java.net.SocketException: Connection reset by peer: socket write error When serving a file How do I use setsockopt(SO_REUSEADDR)?

Examples related to udp

How do I publish a UDP Port on Docker? Simple UDP example to send and receive data from same socket Is SMTP based on TCP or UDP? What does it mean to bind a multicast (UDP) socket? Sending and receiving UDP packets? How to send only one UDP packet with netcat? How is TeamViewer so fast? TCP vs UDP on video stream Difference between TCP and UDP? What are examples of TCP and UDP in real life?

Examples related to bind

Docker Error bind: address already in use Update Angular model after setting input value with jQuery How to remove an appended element with Jquery and why bind or live is causing elements to repeat How to enable named/bind/DNS full logging? What does it mean to bind a multicast (UDP) socket? Detect user scroll down or scroll up in jQuery Cannot assign requested address using ServerSocket.socketBind jQuery bind/unbind 'scroll' event on $(window) What is the use of the JavaScript 'bind' method? Understanding ASP.NET Eval() and Bind()

Examples related to boost-asio

What does it mean to bind a multicast (UDP) socket?

Examples related to multicast

What does it mean to bind a multicast (UDP) socket? How do you UDP multicast in Python?