Search code examples
clinuxnetwork-programmingudpmulticast

Multiple multicast channels on same machine- specify an address or use INADDR_ANY?


Below is basic code to create a multicast socket on Linux.

I have multiple processes running the below code on one machine, each listening to a different multicast channel. Only the relevant data should be processed by each process.

Two stages in the code require an address, or INADDR_ANY.

Given I will have multiple separate multicast channels running, I'm unsure when I should use INADDR_ANY or specify the address. I don't want a process receiving the wrong multicast data.

// Create socket
int sock = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

// Create multicast group
sockaddr_in mcast_group
memset(&mcast_group, 0, sizeof(mcast_group));
mcast_group.sin_family = AF_INET;
mcast_group.sin_port = htons(mcastPort);
mcast_group.sin_addr.s_addr = INADDR_ANY;                         // INADDR_ANY or  specific address?

// Bind socket to multicast group
bind(sock, (struct sockaddr*)&mcast_group, sizeof(mcast_group));

// Tell Kernel to join multicast group
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group.c_str());
mreq.imr_interface.s_addr = inet_addr(interface.c_str());         // INADDR_ANY or specific address?

setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

Solution

  • If each socket is listening only for multicast packets and not unicast, and only for a single multicast address, you can bind directly to the multicast address:

    sockaddr_in mcast_group;
    memset(&mcast_group, 0, sizeof(mcast_group));
    mcast_group.sin_family = AF_INET;
    mcast_group.sin_port = htons(mcastPort);
    mcast_group.sin_addr.s_addr = inet_addr(group.c_str());  // bind to multicast group
    
    bind(sock, (struct sockaddr*)&mcast_group, sizeof(mcast_group));
    

    Note that you'll still have to join the multicast group.