尽管IP_MULTICAST_LOOP(Linux,C++,UDP),IP_ADD_MEMBERSHIP导致"No device found"



首先,我知道这里有很多关于多播主题的问题。我还看到大多数人的问题是不能启用IP_MULTICAST_LOOP。我已经涵盖了这一点,但最终还是出现了"找不到设备"的错误。

我正在编写一个与环回接口或连接的网络设备一起工作的程序,这取决于用户在硬件方面的操作(插入或拔出电缆)。我正在使用UDP进行数据传输。我在Linux上,用C++编写代码。

当网络电缆插入,比如eth0启动并运行时,一切都很好(我的多播设置工作得很好)。如果只有lo可用(并且根据ifconfig已启动并正在运行),则对的调用

setsockopt(this->socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmReq, sizeof(ipmReq))

使用-1失败,导致errno报告"未找到设备"。

以下是我的MulticastEndpoint类中的相关代码:

MulticastEndpoint::MulticastEndpoint(std::string strMulticastGroup, unsigned short usPort) : m_strMulticastGroup(strMulticastGroup), m_usPort(usPort) {
  this->setSocket(::socket(AF_INET, SOCK_DGRAM, 0));
  memset(&m_saAddrGroup, 0, sizeof(m_saAddrGroup));
  m_saAddrGroup.sin_family = AF_INET;
  m_saAddrGroup.sin_addr.s_addr = inet_addr(m_strMulticastGroup.c_str());
  m_saAddrGroup.sin_port = htons(m_usPort);
  unsigned int unYes = 1;
  bool bOK = false;
  if(setsockopt(this->socket(), SOL_SOCKET, SO_REUSEADDR, &unYes, sizeof(unYes)) >= 0) {
    if(setsockopt(this->socket(), IPPROTO_IP, IP_MULTICAST_LOOP, &unYes, sizeof(unYes)) >= 0) {
      memset(&m_saAddrAny, 0, sizeof(m_saAddrAny));
      m_saAddrAny.sin_family = AF_INET;
      m_saAddrAny.sin_addr.s_addr = htonl(INADDR_ANY);
      m_saAddrAny.sin_port = htons(m_usPort);
      if(bind(this->socket(), (struct sockaddr*)&m_saAddrAny, sizeof(m_saAddrAny)) >= 0) {
        struct ip_mreq ipmReq;
        ipmReq.imr_multiaddr.s_addr = inet_addr(m_strMulticastGroup.c_str());
        ipmReq.imr_interface.s_addr = htonl(INADDR_ANY);
        if(setsockopt(this->socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmReq, sizeof(ipmReq)) >= 0) {
          bOK = true;
        }
      }
    }
  }
  if(!bOK) {
    std::cerr << strerror(errno) << std::endl;
    ::close(this->socket());
    this->setSocket(-1);
  }
  std::cout << this->socket() << std::endl;
}

该类以多播地址CCD_ 9和端口CCD_。setSocket(int)socket()方法是一个简单的setter和getter函数,将套接字存储为实例中的int

有人知道这件事吗?从理论上讲,多播应该只在lo上工作,不是吗?另外,我使用的通用多播地址可能是错误的吗?就我对linux套接字的理解而言,INADDR_ANY也应该涵盖环回接口。在这种情况下,如果这是错误的,请纠正我。

我非常感谢你的启迪。

环回接口通常不支持多播。

如果在eth0启动并运行时运行ifconfig -a,您会看到eth0MULTICAST的标志,而lo没有。

以下是我的一台机器显示的内容:

eth0      Link encap:Ethernet  HWaddr 00:11:22:33:44:55
          inet addr:10.112.161.84  Bcast:10.112.161.127  Mask:255.255.255.192
          inet6 addr: fe80::211:22ff:fe33:4455/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:20001770 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10074436 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4589702477 (4.2 GiB)  TX bytes:2896096295 (2.6 GiB)
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1212663 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1212663 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:60939041 (58.1 MiB)  TX bytes:60939041 (58.1 MiB)

编辑:

为了使其工作,您需要手动打开环回上的多播:

sudo ifconfig lo multicast

一旦这样做,您应该能够在环回上加入多播组,但是您需要为ipmReq.imr_interface指定127.0.0.1而不是INADDR_ANY

最新更新