Когда сокет разрушен, он invokes destroy на его службе. Когда вызывается функция SocketService destroy()
, она отменяет асинхронные операции, вызывая небрасывание close()
. Обработчики для отмененных операций будут отправляться для вызова в пределах io_service
с ошибкой boost::asio::error::operation_aborted
.
Вот полный пример, демонстрирующий документированное поведение:
#include <iostream>
#include <boost/asio.hpp>
void handle_connect(const boost::system::error_code& error)
{
std::cout << "handle_connect: " << error.message() << std::endl;
}
int main()
{
namespace ip = boost::asio::ip;
using ip::tcp;
boost::asio::io_service io_service;
// Create socket with a scoped life.
{
tcp::socket socket(io_service);
socket.async_connect(
tcp::endpoint(ip::address::from_string("1.2.3.4"), 12345),
&handle_connect);
}
io_service.run();
}
И его выход:
handle_connect: Operation canceled
Просто для того, чтобы охарактеризовать это немного больше. Правильно ли, что деструктор сокета разрешен для возврата до вызова обработчика? Поэтому обработчик должен оставаться неподвижным. – NFRCR
@NFRCR Да. Время жизни обработчика не связано со временем жизни сокета, и при необходимости операция будет делать копии обработчика. Если обработчик привязан к нестатической функции-члену, то ответственность за то, чтобы экземпляр, на который он привязан, должен обладать, по крайней мере, продолжительностью, чем у обработчика. Идиома 'enable_shared_from_this', используемая в [учебнике] (http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/tutorial/tutdaytime3.html#boost_asio.tutorial.tutdaytime3.the_tcp_connection_class) является одной способ удовлетворить эту гарантию. –