Boost Asio async_send_to multicast con use_future non funziona
ITNOA
Ho un programma che desidera inviare un messaggio con async_send_to a un gruppo multicast. ma voglio che questa azione sia il blocco non asincrono, quindi uso use_future per raggiungere questo obiettivo come di seguito
gw::BoostMessageSender::BoostMessageSender(const std::string& group_address, const std::string& interface_name, uint16_t port_number, ba::io_context& io_context)
: AbstractMessageSender(group_address, interface_name, port_number)
, io_context(io_context)
, endpoint(ba::ip::address::from_string(group_address), port_number)
, socket(io_context, endpoint.protocol())
{
if (!socket.is_open())
socket.open(endpoint.protocol());
socket.set_option(ba::ip::udp::socket::reuse_address(true));
}
bool gw::BoostMessageSender::send(const std::string& message) noexcept
{
std::future<std::size_t> result = socket.async_send_to(ba::buffer(message), endpoint, ba::use_future);
return result.get() == message.size();
}
E uso questa classe come di seguito
int main()
{
const string group_address = "235.127.1.1";
constexpr uint16_t PORT_NUMBER = 8765;
boost::asio::io_context io_context;
BoostMessageSender message_sender(group_address, "eth1", PORT_NUMBER, io_context);
std::thread t1([&io_context]()
{
io_context.run();
});
this_thread::sleep_for(1s);
message_sender.send("Any bodey there?");
cout << "send message: "; // --- this line is not run never :(((
io_context.stop();
t1.join();
return 0;
}
Il mio problema è perché send messagenon scrive mai nella mia console?
Strano che è, controllo la mia rete con tcpdump -i eth0 -nnSX port 8765e dopo la chiamata async_send_toposso vedere il messaggio multicast inviato alla rete, ma result.get()non restituisco mai il risultato e si blocca su quello.
Dov'è il mio errore?
Provo questo codice sulle piattaforme sottostanti
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
Risposte
io_context::run restituisce quando non ci sono lavori in sospeso da eseguire.
È possibile creare protezione del lavoro per garantire che l'esecuzione non finisca anche se non sono state avviate attività asincrone. Usa make_work_guardfunzione:
boost::asio::io_context io_context;
auto workGuard = boost::asio::make_work_guard(io_context);