我几个小时都在努力解决问题: 我想将一个提升asio udo套接字连接到端点。在IPv4中执行此操作没有问题。但是如果我尝试在IPv6中做同样的事情,我会得到一个错误代码“无效的参数”。
using boost::asio::ip::udp;
struct UdpConnectionParams
{
udp::endpoint m_localEndpoint;
udp::endpoint m_remoteEndpoint;
}
boost::system::error_code setupUdpConnection(udp::socket& p_socket, const UdpConnectionParams& p_params)
{
// close socket
boost::system::error_code h_ignoreError;
p_socket.close(h_ignoreError);
// variables for kind of UDP connection
udp h_protocol(udp::v4());
bool h_shallBind{false};
bool h_shallConnect{false};
// determine kind of connection
if(p_params.m_localEndpoint != udp::endpoint())
{
h_protocol = p_params.m_localEndpoint.protocol();
h_shallBind = true;
}
if(p_params.m_remoteEndpoint != udp::endpoint())
{
h_protocol = p_params.m_remoteEndpoint.protocol();
h_shallConnect = true;
}
if(!h_shallBind && !h_shallConnect)
{
// no endpoint specified, return error
return boost::system::error_code(ENetworkErrorCode::NO_ENDPOINT_SPECIFIED, NetworkErrorCategory::getCategory());
}
try
{
p_socket.open(h_protocol);
//bind socket to certain endpoint
if(h_shallBind)
{
p_socket.bind(p_params.m_localEndpoint);
}
//connect socket to client. Thus it is possible to use p_socket.send()
if(h_shallConnect)
{
p_socket.connect(p_params.m_remoteEndpoint);
}
}
catch (boost::system::system_error& h_error)
{
p_socket.close(h_ignoreError);
return h_error.code();
}
// no error
return boost::system::error_code();
}
int main()
{
boost::asio::io_service service;
udp::socket socket(service);
boost::system::error_code error;
UdpConnectionParams params;
params.m_localEndpoint = udp::endpoint(udp::v6(), 55555);
params.m_remoteEndpoint = udp::endpoint(boost::asio::ip::address_v6::from_string("ff01::101"), 55555);
error = setupUdpConnection(socket, params);
cout << error << error.message() << endl; // "invalid argument"
return 0;
}
我没有得到任何错误的唯一方法是使用localhost IP地址(:: 1)。如果我将套接字绑定到端点没有区别。 我做错了什么?
答案 0 :(得分:2)
我做错了什么?
问题是您未在所使用的IPv6地址中指定接口索引/范围。 IPv6多播地址需要指定范围,以便网络堆栈知道您的计算机的哪个本地网络接口将IP地址与之关联。
即。而不是:
boost::asio::ip::address_v6::from_string("ff01::101"), 55555);
你需要这样的东西:
boost::asio::ip::address_v6::from_string("ff01::101%eth0"), 55555);
(%符号后面的后缀取决于您要使用的网络接口的名称,当然)
(作为旁注,“ff01 ::”前缀用于节点本地IPv6多播组,这意味着您的UDP数据包只会转到在同一台计算机上运行的其他程序。如果这是您的意图,那么另一方面,如果你想让你的UDP数据包到达同一局域网上的其他计算机,你会想要使用“ff02 ::”或“ff12 ::”前缀(ff02 ::将用于众所周知的多播地址,ff12 ::将用于临时多播地址。。有关详细信息,请参阅the Wikipedia page上的“多播地址范围”表。