使用use_future的多播Boost Asio async_recieve_与async_send_to不能同时工作 [英] Boost Asio async_recieve_from multicast with use_future does not work simultaneously with async_send_to

查看:117
本文介绍了使用use_future的多播Boost Asio async_recieve_与async_send_to不能同时工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ITNOA

我想编写如下所示的可以同时发送和接收多播的程序

I want to write program that send and receive multicast simultaneously like below

int main()
{
    const string group_address = "235.127.1.1";
    constexpr uint16_t PORT_NUMBER = 8765;

    boost::asio::io_context io_context;
    auto work_guard = boost::asio::make_work_guard(io_context);

    BoostMessageSender message_sender(group_address, "eth1", PORT_NUMBER, io_context);
    BoostMessageReceiver message_receiver(group_address, "eth1", PORT_NUMBER, io_context);

    std::thread t1([&io_context]()
        {
            cout << __LINE__ << endl;
            io_context.run();
        });

    this_thread::sleep_for(1s);

    std::array<char, 20> data = {};
    auto result = std::async(std::launch::async, [&message_receiver, &data]()
        {
                message_receiver.receive(gw::buffer(data));
                cout << " receive finished" << endl; // does not reach this line :(((
        });

    this_thread::sleep_for(1s);
    message_sender.send("Any body there!");

    result.wait(); // Raise exception what(): std::future_error: No associated state
    cout << "receive message: ";
    std::copy(std::begin(data),
          std::end(data),
          std::ostream_iterator<char>(std::cout, ""));

    io_context.stop();
    t1.join();
    return 0;
}

我的问题是为什么result.wait()引发异常?

My problem is why result.wait() cause to raise exception?

可能重要的一点是,当我删除 message_sender.send 行时,该程序不会引发任何异常,并且 result.wait()块行直到结束.但是当添加 message_sender.send 行时,此程序引发异常并且无法正常工作.

the maybe important note that is when I remove message_sender.send line, this program does not raise any exception and line of result.wait() block until end. but when line of message_sender.send added, this program raise exception and does not work properly.

我的message_sender等于代码.

My message_sender is equal to this code.

我的message_receiver如下所示

And my message_receiver is like below

BoostMessageReceiver::BoostMessageReceiver(const std::string& group_address, const std::string& interface_name, uint16_t port_number, ba::io_context& io_context)
    : AbstractMessageReceiver(group_address, interface_name, port_number)
    , io_context(io_context)
    , listen_endpoint(ba::ip::address_v4::any(), port_number)
    , socket(io_context)
{
    socket.open(listen_endpoint.protocol());
    socket.set_option(ba::ip::udp::socket::reuse_address(true));
    socket.bind(listen_endpoint);

    // Join to multicast group
    socket.set_option(ba::ip::multicast::enable_loopback(true));
    socket.set_option(ba::ip::multicast::join_group(ba::ip::address::from_string(group_address)));
}

std::pair<bool, std::size_t> BoostMessageReceiver::receive(const AbstractMessageReceiver::MutableBuffer& buffer) noexcept
{
    ba::ip::udp::endpoint sender_endpoint;

    std::future<std::size_t> result = socket.async_receive_from(ba::buffer(buffer.data(), buffer.size()), sender_endpoint, ba::use_future);

    return std::make_pair(result.get() != 0, result.get());
}

我哪里错了?

我在以下平台上测试了这些代码

I test these code on below platforms

Visual Studio 2019 16.7.4
Windows 10 1909 latest update
Boost 1.73.0

Ubuntu 20.04.1 LTS
GCC 9.3.0
Boost 1.71.0

推荐答案

您将获得 no_state ,因为只能调用 future 上的 get 一次.

You are getting no_state because get on future can be called only once.

下面

std::make_pair(result.get() != 0, result.get());

get 被调用两次.

请参见参考:

注意事项鼓励实现在以下情况下检测情况:调用前有效()为false并抛出一个std :: future_error并带有std :: future_errc :: no_state的错误状态.

Notes The implementations are encouraged to detect the case when valid() is false before the call and throw a std::future_error with an error condition of std::future_errc::no_state.

在第一次调用 get 后, valid 返回 false .

After first call of get, valid returns false.

这篇关于使用use_future的多播Boost Asio async_recieve_与async_send_to不能同时工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆