Асинхронные операции не завершаются немедленно.Ваш код выглядит так, как вы ожидаете.
Упрощение кода до:
Live On Coliru
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::udp;
int main() {
std::cout << std::boolalpha;
boost::asio::io_context io;
boost::asio::ip::udp::socket s {io, udp::v4()};
boost::asio::ip::udp::endpoint const ep {{}, 9999};
auto trace = [&s](char const* caption) { std::cout << caption << s.is_open() << std::endl; };
auto handler = [=](boost::system::error_code, size_t) { trace("handler: "); };
trace("main #1: ");
char buff[200] = {};
s.async_send_to(boost::asio::buffer(buff), ep, handler);
trace("main #2: ");
s.close();
s.async_send_to(boost::asio::buffer(buff), ep, handler);
trace("main #3: ");
s.close();
io.run();
}
Имеет смысл, что обработчик запускается только ПОСЛЕ io.run()
;И, очевидно, сокет открыт только до тех пор, пока не закроется в первый раз:
main #1: true
main #2: true
main #3: false
handler: false
handler: false
Это точно ожидаемо.Таким образом, либо вы должны обрабатывать ошибки:
Live On Coliru
auto trace = [&s](char const* caption) { std::cout << caption << (s.is_open()?"open":"closed") << std::endl; };
auto handler = [=](boost::system::error_code ec, size_t) {
trace(("handler(" + ec.message() + "): ").c_str());
};
Печать вместо:
main #1: open
main #2: open
main #3: closed
handler(Success): closed
handler(Bad file descriptor): closed
Примечание , что, возможно, удивительно, но первая операция отправки все же прошла успешно.Вопреки тому, что я ожидал, это указывает на то, что отправка фактически инициируется прямо при вызове async_send_to
, но завершение задерживается до тех пор, пока io.run()
(сокет все еще показан как уже закрытый).
А может быть, вам вообще не нужны были асинхронные операции:
Live On Coliru
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::udp;
int main() {
std::cout << std::boolalpha;
boost::asio::io_context io;
boost::asio::ip::udp::socket s {io, udp::v4()};
boost::asio::ip::udp::endpoint const ep {{}, 9999};
auto trace = [&s](char const* caption) { std::cout << caption << s.is_open() << std::endl; };
trace("main #1: ");
char buff[200] = {};
try {
/*size_t wlen =*/ s.send_to(boost::asio::buffer(buff), ep);
trace("sent #1: ");
} catch(boost::system::system_error const& e) {
std::cout << "Send #1 failed: " << e.code().message() << std::endl;
}
trace("main #2: ");
s.close();
try {
/*size_t wlen =*/ s.send_to(boost::asio::buffer(buff), ep);
trace("sent #2: ");
} catch(boost::system::system_error const& e) {
std::cout << "Send #2 failed: " << e.code().message() << std::endl;
}
trace("main #3: ");
s.close();
io.run();
}
Печать
main #1: true
sent #1: true
main #2: true
Send #2 failed: Bad file descriptor
main #3: false