C 多接口多播中任意特定接口与INADDR_的套接字绑定
我正在尝试编写多播服务器。我有两个问题:C 多接口多播中任意特定接口与INADDR_的套接字绑定,c,sockets,networking,udp,multicast,C,Sockets,Networking,Udp,Multicast,我正在尝试编写多播服务器。我有两个问题: 如何在多个接口(如以太网/wifi接口)上发送多播公告。我是否需要为每个接口和绑定创建多个套接字 当使用INADDR_任意地址绑定套接字时,描述符准备好执行I/O操作(使用select调用),但当我使用特定接口地址(如以太网/wifi)绑定时,描述符不准备执行任何操作,它仅停留在select api。 那么,使用默认地址(INADDR_ANY)绑定套接字与使用特定接口地址绑定套接字之间有什么区别呢 int sd = socket(AF_INET, SOC
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()");
}
当套接字id与INADD_绑定时,任何地址select都将返回,并且我可以使用文件描述符读取,但当与特定接口绑定时,select将永不返回,因为没有可读取的文件描述符。将套接字与特定地址绑定是将其锁定到设备的通用方法。这种方法有点过时,因为在程序启动后,可以在设备上更改地址。总的来说,我建议绑定到INADDR_ANY 您可以随时更改套接字上的输出多播设备 可考虑的备选方案: man 7 ip:
IP_MULTICAST_ALL-传送到所有设备(默认值1)
IP_MULTICAST_IF-我很确定这只会设置输出设备 man 7插座:
因此,我们必须提供设备 只需在选项上玩一点,看看结果如何
setsockopt()
,并为每个接口提供适当的连接参数。你只需要一个插座
它确定您通过发送和接收的IP地址。当您绑定到
INADDR\u ANY
并调用select
时,是否检查select
返回的内容?并检查sockfd\u set
中设置了哪些描述符?说到错误,如果任何系统调用失败,您应该真正打印(可能需要的帮助)。我已将套接字描述符添加到sockfd_集,并且select将在使用INADDR_绑定时返回1,之后我将使用FD_ISSET检查套接字描述符,并对特定描述符执行读取操作。在其他情况下,select根本不返回,因为我没有提到超时。在接收多播时,始终绑定到INADDR\u ANY
。在Linux中,如果绑定到特定接口,将无法接收multicast.IP_multicast_,如果设置了为套接字发送相关IGMP消息的接口。没有别的了。
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");