考虑下面的代码,
我正在尝试绑定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);
}
答案 0 :(得分:1)
我相信你还需要bind
关于你想要收听的特定多播地址,而不仅仅是setsockopt
电话 - 后者也是必要的,以确保网卡和IGMP也做对了。
答案 1 :(得分:0)
好的,我让实例工作了,所以我知道问题出在哪里。 bind()
必须针对多播IP地址出现:
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
。直到我更改了它,它才根本不会收到广播的数据包。