Boost UDP 多播接收器:set_option:请求的地址在其上下文中无效

Posted

技术标签:

【中文标题】Boost UDP 多播接收器:set_option:请求的地址在其上下文中无效【英文标题】:Boost UDP multicast receiver: set_option: The requested address is not valid in its context 【发布时间】:2018-03-03 22:17:51 【问题描述】:

我正在关注 Boost 的 UDP 时间服务器教程here .我用这些修改代码以获得预定义的值:

short multicast_port = 13;  // (in class receiver)

在main()中:

//if (argc != 3) and the code for argv that follows are commented out    
receiver r(io_context, boost::asio::ip::make_address("127.0.0.1"), boost::asio::ip::make_address("127.0.0.1")); //

抛出此错误:

set_option: The requested address is not valid in its context

我试过“0.0.0.0”和“127.0.0.1”等值。仍然得到同样的错误。有人可以帮我找出问题所在吗?

为了澄清事情,这是我使用的代码:

#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <array>
#include <string>
using boost::asio::ip::udp;
using std::cout;
using std::cin;
using std::endl;

class receiver

private:
    boost::asio::ip::udp::socket socket_;
    boost::asio::ip::udp::endpoint sender_endpoint_;
    std::array<char, 1024> data_;
    short multicast_port = 13000;

public:
    receiver(boost::asio::io_context& io_context,
        const boost::asio::ip::address& listen_address,
        const boost::asio::ip::address& multicast_address)
        : socket_(io_context)
    
        // Create the socket so that multiple may be bound to the same address.
        boost::asio::ip::udp::endpoint listen_endpoint(
            listen_address, multicast_port);
        socket_.open(listen_endpoint.protocol());
        socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        socket_.bind(listen_endpoint);

        // Join the multicast group.
        socket_.set_option(
            boost::asio::ip::multicast::join_group(multicast_address));

        do_receive();
    

private:
    void do_receive()
    
        socket_.async_receive_from(
            boost::asio::buffer(data_), sender_endpoint_,
            [this](boost::system::error_code ec, std::size_t length)
        
            if (!ec)
            
                std::cout.write(data_.data(), length);
                std::cout << std::endl;

                do_receive();
            
        );
    
;

int main(int argc, char* argv[])

    try
    
        boost::asio::io_context io_context;
        receiver r(io_context, boost::asio::ip::make_address("127.0.0.1"), boost::asio::ip::make_address("127.0.0.1"));
        io_context.run();
    
    catch (std::exception& e)
    
        std::cerr << "Exception: " << e.what() << "\n";
    


    return 0;
    

【问题讨论】:

1024以下的端口号有特权,你需要是某种“管理员”或“超级用户”才能使用1024以下的端口。 此外,您显示的小代码不会调用set_option 或执行任何特定于多播的操作。 Minimal, Complete, and Verifiable Example 将大大有助于我们为您提供帮助。 我将端口更改为 13000,但仍然出错。我只是按照链接中的示例代码。我假设它已经过测试,因为它是作为官方文档发布的。 停止转发此问题。 【参考方案1】:

构造函数的第三个参数是多播组地址。

127.0.0.1 不是组播组地址,0.0.0.0 也不是。

请参阅您的来源。

【讨论】:

【参考方案2】:

也许太久以前无法回答,但我遇到了同样的问题,也许其他人也面临同样的问题。所以这可能不是最好的解决方案,但至少是让它发挥作用的某种方式。

基本上,您使用以太网适配器 IP 加入多播组,这似乎比在您正在侦听的端口上打开所有以太网适配器更自然。 小心使用有效的 IP,因为如果不是,boost 会抛出异常。到目前为止,我发现的唯一解决方案是在接收器方法调用周围使用 try / catch。

当您尝试加入多播组时,您似乎需要某个以太网适配器的 IP 地址。我建议编辑它并使用静态 IP 地址(系统 > 网络 > 以太网连接)。

至于代码,只需将这一行改成:

// Join the multicast group.
socket_.set_option(
  boost::asio::ip::multicast::join_group(multicast_address.to_v4(), listen_address.to_v4()));

我不确定 .to_v4() 是否需要,但它没有伤害。

【讨论】:

以上是关于Boost UDP 多播接收器:set_option:请求的地址在其上下文中无效的主要内容,如果未能解决你的问题,请参考以下文章

绑定多播 (UDP) 套接字是啥意思?

未使用 PYQT5 多播 UDP 接收数据报

使用 boost::asio 在同一主机上多播消息

如何接收组播 UDP?

udp广播,单播,多播

NodeJS 数据报 - 接收 IPv6 多播