C 在特定接口上接收多播
C++ receiving multicast on particular interface
ip_add_membership上的文档说:
ip_add_membership(由于Linux 1.2( 加入一个多播组。参数是IP_MREQN结构。
struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast group address */ struct in_addr imr_address; /* IP address of local interface */ int imr_ifindex; /* interface index */ }; imr_multiaddr contains the address of the multicast group the appli‐ cation wants to join or leave. It must be a valid multicast address (or setsockopt(2) fails with the error EINVAL). imr_address is the address of the local interface with which the system should join the multicast group; if it is equal to INADDR_ANY, an appropriate inter‐ face is chosen by the system. imr_ifindex is the interface index of the interface that should join/leave the imr_multiaddr group, or 0 to indicate any interface.
因此,我有一个IP 192.168.1.5的接口" ETH0"。我想将此接口加入多播组225.1.1.1。我对如何正确设置IP_MREQN结构有些困惑?我找到了2种可能的方法:
1。
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;
2。
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");
和第三种方式是使用so_bindtodevice套接字选项。
我的问题是。
1(什么是将特定接口加入多播组的正确方法?
2(imr_address和imr_ifindex之间的功能差异是什么?
3(选项so_bindtodevice如何有用?
编辑:我做了一些研究。
假设我有两个网络接口:IP 192.168.1.5和IP的ETH0和IP 192.168.1.255,并且我在ETH0上获得了IP 192.168.1.5。
。这些方式工作正确(我在eth0上收到多播消息(:
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;
或
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");
或明显
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth0");
甚至
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth0");
和这些方式 do (我在eth0上没有多播消息(:
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth1");
和
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth1");
我一直使用旧的 struct ip_mreq
而不是 struct ip_mreqn
,因为两者都得到了支持。该结构没有索引字段,因此您需要设置的内容不太模棱两可。
struct ip_mreq
{
/* IP multicast address of group. */
struct in_addr imr_multiaddr;
/* Local IP address of interface. */
struct in_addr imr_interface;
};
您然后将其设置为:
struct ip_mreq group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_interface.s_addr = inet_addr("192.168.1.5");
ip_mreqn
用于在linux/net/ipv4/igmp.c
(Linux 5.13(的内核源代码中找到网络接口设备,如下。
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{
struct net_device *dev = NULL;
struct in_device *idev = NULL;
if (imr->imr_ifindex) {
idev = inetdev_by_index(net, imr->imr_ifindex);
return idev;
}
if (imr->imr_address.s_addr) {
dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
if (!dev)
return NULL;
}
if (!dev) {
struct rtable *rt = ip_route_output(net,
imr->imr_multiaddr.s_addr,
0, 0, 0);
if (!IS_ERR(rt)) {
dev = rt->dst.dev;
ip_rt_put(rt);
}
}
if (dev) {
imr->imr_ifindex = dev->ifindex;
idev = __in_dev_get_rtnl(dev);
}
return idev;
}
imr->imr_ifindex
首先用于搜索设备。如果未找到,则使用imr->imr_address
。
相关文章:
- 如何使用虚幻引擎"filter"多播?
- 无法在 Windows 10 上加入 IPV6 多播组
- C++:继承自基类和具有公共基接口的多个接口
- 如何在 Linux 上的 C/C++ 中使用 ipv6 udp 套接字进行多播?
- IPv6 多播在局域网中不起作用
- 简单的多播应用程序无法在同一网络上的不同计算机上运行
- Linux VS Windows 上的 UDP 多播差异
- 在覆盆子Pi路由器上进行多播
- C 在特定接口上接收多播
- 如何在C++中实现"Registry pattern",使用单个注册表实现多个接口
- 为什么Zeromq PGM多播未接收多播消息?(C ,Windows)
- Ubuntu C 多播双休假组消息
- 如何从已经订阅的组中接收多播数据包
- 我是否需要2个插座来进行多播和单播
- 使用 Boost ASIO 在 macOS 上到特定接口的多播
- C++的多个接口只在返回类型上不同
- 如何正确接收多播UDP数据包
- 如何为多播指定所有接口
- 多个接口上的多个组播
- 在所有接口上侦听多播