简体   繁体   中英

How to implement client-server architecture over IP multicast in Boost.Asio?

I'm trying to implement two-way multicast UDP communication using Boost.Asio. Actually what I need is client-server architecture.

I used these tutorials and examples and modified them:

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/multicast/receiver.cpp

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/multicast/sender.cpp

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/futures/daytime_client.cpp

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/tutorial/tutdaytime6.html

Futures daytime client and daytime server works perfectly fine, unless I use multicast address for it, which I have to. It just doesn't communicate.

I modified client's daytime function and server example's constructor to look like this:

Client:

    void get_daytime(boost::asio::io_context& io_context,
                 const boost::asio::ip::address& listenAddress,
                 const boost::asio::ip::address& multicastAddress)
{
    try
    {
        udp::socket socket(io_context);

        boost::asio::ip::udp::endpoint listenEndpoint(listenAddress, multicastPort);
        socket.open(listenEndpoint.protocol());
        socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        socket.bind(listenEndpoint);
        socket.set_option(boost::asio::ip::multicast::join_group(multicastAddress));


        std::array<char, 1U> send_buf  = {{ 0 }};
        std::future<std::size_t> send_length =
                socket.async_send_to(boost::asio::buffer(send_buf),
                                     listenEndpoint,
                                     boost::asio::use_future);

        send_length.get();

        std::array<char, 128U> recv_buf{};
        udp::endpoint sender_endpoint;
        std::future<std::size_t> recv_length =
                socket.async_receive_from(
                        boost::asio::buffer(recv_buf),
                        sender_endpoint,
                        boost::asio::use_future);

        std::cout.write(
                recv_buf.data(),
                recv_length.get()); // Blocks until receive is complete.
    }
    catch (std::system_error& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

Server:

udp_server(boost::asio::io_context& io_context,
               const boost::asio::ip::address& listenAddress,
               const boost::asio::ip::address_v4& multicastAddress)
               : socket_(io_context)
    {
        boost::asio::ip::udp::endpoint listenEndpoint(listenAddress, multicastPort);
        socket_.open(listenEndpoint.protocol());
        socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        socket_.bind(listenEndpoint);
        socket_.set_option(boost::asio::ip::multicast::join_group(multicastAddress));
        start_receive();
    }

How should I modify the code in order to make it work over multicast? Thanks.

I found a solution to my problem. I didn't have to modify getDaytime() function, though my udp_server() constructor now looks like this:

udp_server(boost::asio::io_context& io_context)
            : socket_(io_context, udp::endpoint(boost::asio::ip::make_address("0.0.0.0"), 60000))
    {
        socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address("239.192.0.1")));
        start_receive();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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