boost asio udp socket connect(IPv6)上的无效参数

时间:2017-10-05 13:56:41

标签: c++ boost udp ipv6 asio

我几个小时都在努力解决问题: 我想将一个提升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)。如果我将套接字绑定到端点没有区别。 我做错了什么?

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上的“多播地址范围”表。