0

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.

eskimo9
  • 753
  • 10
  • 24
  • 1
    I don't think you need the `setsockopt(IP_MULTICAST_IP)` if you are a receiver. I think that's for multicast senders. Also, I just noticed that `imr.imr_interface` is not set correctly. Shouldn't that be set to `localEndPoint.sin_addr`? – Celada May 04 '12 at 19:05
  • Thanks Celada, you were right about `imr.imr_interface`. My client is sending and receiving, so I do need all the `setsockopt`s there. I got it working in a test main class in Linux (Ubuntu 10 with gcc 4 (I think 4.3)) but it still gives me the same `errno` when I try to load in Android, which is where I need it. Without worrying about why I'm using native sockets in Android, any ideas what might be different here? – eskimo9 May 08 '12 at 00:31
  • OK seem to have solved the problem, but I have no idea what I did. The test case was working in Linux. I moved to Android in Eclipse, kept getting errno 19 again. Tried setting preferred network, but it wouldn't change (security permissions are fine). On the device, went into Ethernet Settings, it auto-refreshed and after that it worked. Anyone know why? Guess I need to find how to get my app to check/reconfigure ethernet settings on start. – eskimo9 May 08 '12 at 03:18

0 Answers0