2014-01-07 3 views
1
asio::io_service ioService; 
asio::ip::tcp::socket* socket = new asio::ip::tcp::socket(ioService); 
socket->async_connect(endpoint, handler); 
delete socket; 

Деструктор Socket должен закрыть розетку. Но может ли асинхронный бэкэнд справиться с этим? Отменит ли он асинхронную операцию и вызовет обработчик? Возможно нет?C++ Boost. Время жизни объекта Asio

ответ

4

Когда сокет разрушен, он 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 
+0

Просто для того, чтобы охарактеризовать это немного больше. Правильно ли, что деструктор сокета разрешен для возврата до вызова обработчика? Поэтому обработчик должен оставаться неподвижным. – NFRCR

+0

@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) является одной способ удовлетворить эту гарантию. –

0

Почему вы создали сокет, используя new? Это определенно не будет нормальным процессом. Если вы действительно хотите создать socket, используя новый, вы должны закрыть и удалить его в конце своей программы.

Вот пример, просто.

io_service service_; 

ip::tcp::socket sock(service_); 
sock.async_connect(ep, connect_handler); 

deadline_timer t(service_, boost::posix_time::seconds(5)); 
t.async_wait(timeout_handler); 

service_.run(); 
+0

Я действительно не использовать его таким образом. Я пишу потокобезопасные обертки вокруг Asio. В документации не хватает информации о гарантиях и неопределенном поведении, поэтому я просто пытаюсь изучить, как все это за кулисами. – NFRCR

+0

@NFRCR ОК, я не знал вашего скрытого намерения. Спасибо за ваш комментарий. – hyun

Смежные вопросы