如何使多播套接字不接收单播数据?
How can I keep a multicast socket from receiving unicast data
是否有办法防止套接字加入到多播组从接收单播数据定向在同一端口?
一个socket选项或ioctl可能?我看到了https://msdn.microsoft.com/en-us/library/windows/desktop/ms738712%28v=vs.85%29.aspx,但这似乎只是为了过滤哪些主机可以发送多播,而不是谁可以发送单播。
我正在使用Qt应用程序,所以如果有一种方法可以从Qt的套接字框架内做到这一点,那么很好,如果不是,那么恢复到常规的旧伯克利套接字不是问题。
到目前为止我发现的唯一方法是相当黑客-创建第二个UDP套接字并在绑定多播套接字之前将其绑定到端口。我想一定有更好的东西,虽然我还没找到。
更糟的是:您甚至不能确定您只接收到指向您加入的地址的多播流量。您也可以从运行在同一台机器上的其他进程加入的组中接收多播流量,尽管它们与您的程序无关。
最好的(因为最可移植的)解决方案不是尝试用套接字选项来解决这个问题,而是检查接收到的数据包,找出它们的目标,并丢弃您不想接收的数据包。
您可以使用setsockopt(IP_PKTINFO)和recvmsg()来启用接收到的UDP数据包上的各种有用的元信息,包括通常非常有趣的目标IP地址,在您的情况下是一个多播地址。
将套接字与组播地址绑定,加入组播组,从而配置正确的接口。此方法已在linux和OSX上进行了测试。
auto fd = socket(AF_INET, SOCK_DGRAM,0);
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(MULTICAST_PORT);
inet_pton(AF_INET, INTERFACE_ADDRESS, &sa.sin_addr);
struct sockaddr_in multicast;
multicast.sin_family = AF_INET;
multicast.sin_port = htons(MULTICAST_PORT);
inet_pton(AF_INET, MULTICAST_ADDRESS, &multicast.sin_addr);
struct ip_mreqn req = {};
req.imr_ifindex = INTERFACE_INDEX;
req.imr_multiaddr = multicast.sin_addr;
req.imr_address = sa.sin_addr;
setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req))
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &req, sizeof(req))
bind(fd,(struct sockaddr*)&multicast, sizeof(multicast))
可以用ip_mreq
代替ip_mreqn
,这样更便于移植,而且不需要接口索引。但是请注意,对于ipv6,加入多播组需要接口索引。
使用Qt,从快速查看https://doc.qt.io/qt-5/qtnetwork-multicastreceiver-receiver-cpp.html,我认为所有你需要做的是设置绑定调用的QHostAddress到groupAddress4
。无法保证流量将来自哪个设备。
你的解决方案与另一个套接字将无法移植,因为没有明确的方式,一个端口上的单播流量被调度到多个套接字。(即:可能是轮询,可能是第一个绑定取所有…)
- 将空格作为单字符数据类型的输入?
- 家庭作业帮助 - 检查表单按钮上的数据
- 如何从已经订阅的组中接收多播数据包
- 我是否需要2个插座来进行多播和单播
- 将数据表单文本文件读取到数组中时出现问题
- 如何正确接收多播UDP数据包
- 具有Boost C 的多播接收器看不到数据
- 以选定的比特率发送音频数据 - 喊播
- UDP插座(多播)未接收数据(Ubuntu)
- 在Qt上使用QUdpSocket的单播
- 在 ipv6 链接范围单播 udp 客户端-服务器中应用 boost::asio::ip::udp,有时有效,但有时无效
- IP_ADD_MEMBERSHIP套接字上,套接字是否也会侦听单播
- 全局访问单例数据
- Solaris 10 -- 从 recvmsg() 的 UDP 组播数据包中获取 IP 源地址
- ZeroMQ无法在单播IPv6上运行
- 在std::multiset中,如果找到一个元素,有一个函数或算法可以只擦除一个样本(单播或重复)
- 如何使多播套接字不接收单播数据?
- 在RHEL 7上使用c++接收组播数据
- 如何/应该在Qt中创建ui表单和数据成员之间的自动链接
- 使用boost::asio执行单播消息传递