繁体   English   中英

boost asio udp套接字连接(IPv6)上的参数无效

[英]invalid argument on boost asio udp socket connect (IPv6)

我一个小时都在苦苦挣扎:我想将boost 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;
}

我没有错误的唯一方法是使用本地主机IP地址(:: 1)。 如果将套接字绑定到端点也没有区别。 我究竟做错了什么?

我究竟做错了什么?

问题是您没有在使用的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数据包到达同一LAN上的其他计算机,则需要改用“ ff02 ::”或“ ff12 ::”前缀(ff02 ::代表知名多播地址ff12 ::代表临时多播地址。有关详细信息,请参见Wikipedia页面 “多播地址范围”表)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM