I'm trying to write multicast server. I've two questions:
How to send multicast announcements on multiple interfaces like ethernet/ wifi interface. Do I need to create multiple sockets for each interface and bind?
When bind socket with INADDR_ANY address, descriptor is ready to do I/O operation (using select call )but when I bind with specific interface address e.g ethernet/wifi then descriptor is not ready to perform any operation it is stuck at select api only. So what is the difference between binding a socket with default address (INADDR_ANY) or specific interface address?
int sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd < 0) { printf("scoket() failed"); return sd; } int r = -1; int on = 1; if ((r = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on))) < 0) { printf("recv setsockopt(SO_REUSEADDR) failed"); return r; } // add membership to receiving socket struct ip_mreq mreq; memset(&mreq, 0, sizeof(struct ip_mreq)); mreq.imr_interface.s_addr = htonl(INADDR_ANY); mreq.imr_multiaddr.s_addr = inet_addr(MDNS_ADDR); if ((r = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq))) < 0) { printf("recv setsockopt(IP_ADD_MEM) failed"); return r; } // enable loopback in case someone else needs the data if ((r = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &on, sizeof(on))) < 0) { printf("recv setsockopt(IP_MULTICAST_LOOP) failed"); return r; } #ifdef IP_PKTINFO if ((r = setsockopt(sd, SOL_IP, IP_PKTINFO, (char *) &on, sizeof(on))) < 0) { printf("recv setsockopt(IP_PKTINFO) failed"); return r; } #endif /* bind to an address */ struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(MDNS_PORT); //serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /* receive multicast */ serveraddr.sin_addr.s_addr = inet_addr("192.168.10.23"); /* receive multicast */ if ((r = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0) { printf("recv bind()"); }
In thread waiting for descriptors to ready for I/O (basically all are read file descriptors)
FD_ZERO(&sockfd_set);
FD_SET(svr->sockfd, &sockfd_set);
FD_SET(svr->notify_pipe[0], &sockfd_set);
printf("before select\n");
select(max_fd + 1, &sockfd_set, NULL, NULL, NULL);
printf("after select\n");
When socket id bind with INADD_ANY address select will returns and I'm able to read with file descriptor but when bind with specific interface then select never returns coz there is no file descriptors available to read.
INADDR_ANYand then callselect, you do check whatselectreturns? And check what descriptors are set insockfd_set? And talking about error, is any system call fails, you should really print the error (maybe with the help ofstrerror). - Some programmer dudeINADDR_ANY. In Linux, if you bind to a specific interface, you won't be able to receive multicast. - dbush