问题描述
ITNOA
我想编写如下所示的同时发送和接收多播的程序
_retrieveData()
我的问题是为什么result.wait()引发异常?
也许很重要的一点是,当我删除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,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;
}
行时,该程序不会引发任何异常,message_sender.send
块行直到结束。但是当添加result.wait()
行时,该程序会引发异常,并且无法正常运行。
我的message_receiver如下所示
message_sender.send
我哪里错了?
我在以下平台上测试了这些代码
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(),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());
}
解决方法
您得到no_state
是因为get
上的future
只能被调用一次。
下面
std::make_pair(result.get() != 0,result.get());
get
被两次调用。
请参见reference:
注意事项鼓励实现在以下情况下检测情况: 调用前有效()为false并抛出一个std :: future_error并带有 std :: future_errc :: no_state的错误状态。
在第一次调用get
之后,valid
返回false
。