我设置了一个 UDP 非阻塞套接字。我正在创建套接字,绑定它,并像这样加入一个多播组:
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;
}
前 3 个 setsockopt 调用 - MULTICAST_TTL、MULTICAST-IF 和 REUSEADDRESS - 工作正常,并且绑定。然后,当我尝试加入多播组时,它返回 errno 19 - 未找到设备。将 imr 接口地址更改为 INADDR_ANY 意味着找到了设备,但程序不会接收数据包。我已经更改了地址,我知道它在多播范围内。我机器上的 eth0 启用了多播。我已经尝试使用struct ip_mreqn imr
并更改接口以适当地解决,没有变化。我运行了一个堆栈跟踪,但它没有更多信息,只是说 setsockopt 失败并出现 errno 19。
有没有人有任何想法?我在这里有点绝望,我已经在这方面太久了。