I have set a UDP non-blocking socket. I am creating the socket, binding it, and joining a multicast group like this:
int hopLimit = 1;
int bAllowMultiple = 1;
in_addr localAddr;
localAddr.s_addr = 0;
in_addr groupAddress;
groupAddress.s_addr = inet_addr(ADDRESS);
sockaddr_in groupEndPoint;
groupEndPoint.sin_family = AF_INET;
groupEndPoint.sin_addr = groupAddress;
groupEndPoint.sin_port = htons(PORT);
SOCKET udpsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(udpsocket == -1){
printf("Socket fail\n%d\n", errno);
return 1;
}
if(setsockopt(udpsocket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&hopLimit, sizeof(hopLimit))==-1){
printf("sockopt failed: IP_MULTICAST_TTL\n%d\n", errno);
return 1;
}
if(setsockopt(udpsocket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localAddr, sizeof(localAddr))==-1){
printf("sockopt failed: IP_MULTICAST_IF\n%d\n", errno);
return 1;
}
if(setsockopt(udpsocket, SOL_SOCKET, SO_REUSEADDR, &bAllowMultiple, sizeof(bAllowMultiple))==-1){
printf("sockopt failed: SO_REUSEADDR\n%d\n", errno);
return errno;
}
// Set to non-blocking mode
unsigned long bMode = 1;
if(ioctl( udpsocket, FIONBIO, &bMode )==-1){
printf("ioctl failed\n%d\n", errno);
return errno;
}
sockaddr_in localEndPoint;
localEndPoint.sin_family = AF_INET;
localEndPoint.sin_addr.s_addr = localAddr.s_addr;
localEndPoint.sin_port = groupEndPoint.sin_port;
// Bind the socket to the port
int r = bind(udpsocket, (sockaddr*)&localEndPoint, sizeof(localEndPoint));
if (r != 0)
{
printf("Bind failed\n%d\n", errno);
return errno;
}
// Join the multicast group
struct ip_mreq imr;
imr.imr_multiaddr = groupEndPoint.sin_addr;
imr.imr_interface.s_addr = groupEndPoint.sin_addr.s_addr;
r = setsockopt(udpsocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr));
printf("%d\n",r);
if (r == -1){
printf("sockopt failed: IP_ADD_MEMBERSHIP\n%d\n", errno);
return errno;
}
The first 3 setsockopt calls - MULTICAST_TTL, MULTICAST-IF and REUSEADDRESS - work fine, and it binds. When I then try to join the multicast group it returns errno 19 - Device Not Found. Changing the imr interface address to INADDR_ANY means the device is found, but the program won't receive packets. I've changed the ADDRESS, I know it is in the multicast range. eth0 on my machine has multicast enabled. I've tried using struct ip_mreqn imr
and changed interface to address appropriately, no change. I ran a stack trace, but it's no more informative, just says setsockopt failed with errno 19.
Does anyone have any ideas? I'm a bit desperate here, I've been on this for way too long.