C++在特定接口(interface)上接收多播

标签 c++ c network-programming multicast

关于 IP_ADD_MEMBERSHIP 的文档说:

IP_ADD_MEMBERSHIP (since Linux 1.2) Join a multicast group. Argument is an ip_mreqn structure.

      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.

所以我有一个接口(interface)“eth0”,IP 为 192.168.1.5。我想将此接口(interface)加入多播组 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) 将特定接口(interface)加入多播组的正确方法是什么?

2) imr_address 和 imr_ifindex 的功能区别是什么?

3) 选项 SO_BINDTODEVICE 有何用处?

编辑:我做了一些研究。

假设我有两个网络接口(interface):eth0 的 ip 192.168.1.5 和 eth1 的 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");

这些方法不会(我不会在 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");

关于C++在特定接口(interface)上接收多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48624503/

相关文章:

c - 在设备固件中支持 WinUSB

c++ - 从子类调用父虚函数

c++ - 带彩虹括号的 Vim 折叠

c - 解码器函数在 C 中返回垃圾字符串。如何修复?

objective-c - 如何在 Objective-C 中在自己的文件中定义一个 c 结构并将该结构作为参数传递

javascript - XMLHttpRequest 中 TCP 握手究竟何时发生?

c++ - "Destination address required"尝试通过 SOCK_RAW 套接字发送数据时

C++跨平台轻量级文件、线程和处理库

c++ - `ncurses` 函数 `wgetstr` 正在修改我的变量

c# - 如何在多线程 C# 中使用 TCP 客户端/监听器?