IP_ADD_MEMBERSHIP套接字上,套接字是否也会侦听单播

IP_ADD_MEMBERSHIP on a socket, will the socket listen to unicast also?

本文关键字:套接字 单播 ADD MEMBERSHIP IP 是否      更新时间:2023-10-16

考虑下面的代码,

我正在尝试为多播绑定 UDP 套接字。
我已将其绑定到特定端口,并为要侦听的地址设置了IP_ADD_MEMBERSHIP

我的问题:套接字会收到绑定到该端口的单播 UDP 数据包吗?如果是这样,我该如何防止?我只希望接收多播。

int fd;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
    perror("socket");
    exit(1);
}
u_int yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
{
    perror("Reusing ADDR failed");
    exit(1);
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = (source_iface.empty()
                          ? htonl(INADDR_ANY)
                          : inet_addr(source_iface.c_str()));
if (bind(fd,(struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    perror("bind");
    exit(1);
}
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group.c_str());
mreq.imr_interface.s_addr = (source_iface.empty()
                               ? htonl(INADDR_ANY)
                               : inet_addr(source_iface.c_str()));
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
    perror("setsockopt");
    exit(1);
}
我相信

您还需要bind要侦听的特定组播地址,而不仅仅是在setsockopt呼叫中 - 后者对于确保网卡和IGMP也做正确的事情也是必要的。

另请参阅绑定多播 (UDP) 套接字是什么意思?

好的,我让我的实例工作,所以我知道问题是什么。必须针对多播 IP 地址进行bind()

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = (group.empty()
                          ? htonl(INADDR_ANY)   // <-- this will work here but not below
                          : inet_addr(group.c_str()));
if (bind(fd,(struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    perror("bind");
    exit(1);
}

这里的区别是group而不是source_iface.在我更改之前,它根本不会接收广播数据包。