Boost UDP multicast receiver: set_option: The requested address is not valid in its context

为君一笑 提交于 2019-12-14 03:25:09

问题


I am following Boost's UDP Time server tutorial here . I modify the code with these for predefined values:

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

and in 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")); //

This error is thrown:

set_option: The requested address is not valid in its context

I have tried "0.0.0.0" and "127.0.0.1" and other values. Still get the same error. Could someone please help me figuring out what went wrong?

To clarify things, this is the code I use:

#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;
}    

回答1:


The third parameter to the constructor is a multicast group address.

127.0.0.1 is not a multicast group address, and neither is 0.0.0.0.

Refer to your source.




回答2:


Maybe a bit too long ago to answer, but I've had the same problem and maybe someone else faces the same problem. So this is probably not the best solution, but at least some way to get it to work.

Basically you join the multicast group with the ethernet adapters IP, which seems more natural than opening all ethernet adapters on the port you're listening to. Be careful to use a valid IP because boost throws an exception if not. The only solution I found so far is using a try / catch around the receiver method call.

When you try to join a multicast group it seems you need the IP address of one of your ethernet adapters. I recommend editing it and use a static IP address (System > Network > Ethernet Connections).

As for the code, only this line needs to be changed into:

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

I'm not sure if the .to_v4() is needed but it didn't hurt.



来源:https://stackoverflow.com/questions/49089819/boost-udp-multicast-receiver-set-option-the-requested-address-is-not-valid-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!