我有一个有两个接口的主机。在我的具体情况下,我尝试使用boost::asio::ip::multicast::join_group
加入多播组,这似乎只有在我使用包含本地地址的构造函数时才能工作。但是我事先并不知道连接到将进行多播的远程主机的本地接口的IP地址。但我知道这将是eth1。当然,我可以使它可配置,但这似乎引入了一个无用的错误配置机会,看看如何为接口和我的应用程序配置相同的地址。
理想情况下,从界面创建boost::asio::endpoint
或boost::asio::address
而不是某种我错过的地址会有明显的方法。或者,我当然会对任何其他推断接口Ip的方式感到满意,无论有没有提供IP的DHCP服务器,都可以使用。
是否有正确的方法可以做或者我应该相信用户永远不会碰到配置?
为了确保这不完全是XY问题,这是我在测试加入多播组时使用的代码:
m_socket.open(boost_ip::udp::v4());
m_socket.bind(boost_ip::udp::endpoint(boost_ip::udp::v4(), listeningPort));
m_socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
m_socket.set_option(boost::asio::ip::multicast::join_group(
boost::asio::ip::address::from_string("225.x.x.10").to_v4(), // remote
boost::asio::ip::address::from_string("192.x.x.3").to_v4())); // local
这确实有效但当我丢弃最后一行不依赖于当前本地地址(可能在部署中更改)时,我不再收到任何数据包。
答案 0 :(得分:1)
组播使用IGMP协议形成组播组。由于IGMP在网络层上运行,因此需要加入组播组的端点的本地IP地址。
应用程序应等待指示已将ip地址分配给以太网接口的事件,然后调用join_group方法加入多播组。
答案 1 :(得分:1)
我自己想出了一个问题的答案。这对我有用,但我会保留问题,以防任何人有更直接的解决方案。
我决定使用<ifaddrs.h>
来找到我当前的接口IP并使用它加入多播组。这是我最终确定我的ip的代码:
#include <ifaddrs.h>
#include <boost/asio.hpp>
#include <cstring>
std::string getInterfaceAddress(const std::string & interfaceName)
{
ifaddrs* firstNetIf = 0;
getifaddrs(&firstNetIf);
ifaddrs* netIf = 0;
for(netIf = firstNetIf; netIf != 0; netIf = netIf->ifa_next)
{
if(netIf->ifa_addr->sa_family == AF_INET && std::strncmp(netIf->ifa_name, interfaceName.c_str(), interfaceName.length()) == 0)
{
break;
}
}
unsigned long address =
netIf != 0 ? reinterpret_cast<sockaddr_in*>(netIf->ifa_addr)->sin_addr.s_addr : 0;
if(firstNetIf != 0)
{
freeifaddrs(firstNetIf);
}
return boost::asio::ip::address_v4(htonl(address)).to_string();
}
当然,在我的情况下,我可以与"eth1"
进行比较并直接返回boost::asio::ip::address
,但事实证明此代码也可以在其他地方使用。