Вопрос

I have the following code:

 void GnutellaApp::HandleRead (boost::asio::ip::tcp::socket& socket)
{
     char buf[128];
     try {
     boost::asio::async_read(   socket,
                                boost::asio::buffer(buf),
                                boost::asio::transfer_all(),
                                boost::bind(&GnutellaApp::HandleRead,
                                            this,
                                            boost::ref(socket)
                                            )
                            );
     }
        catch (boost::system::system_error const& e)
        {
            std::cout << "Warning:  " << e.what() << std::endl;
        }
}

When HandleRead is called and async_read is executed, its throwing an exception. In order to asynchronously wait for next request we need to call async_read again, right? First call to async_read succeeds.

i am getting following exception

I am getting following exception

Gnutella.exe!std::_Ref_count_base::_Incwref() Line 113  C++
    Gnutella.exe!std::_Ptr_base<void>::_Resetw<void>(void * _Other_ptr, std::_Ref_count_base * _Other_rep) Line 458 C++
    Gnutella.exe!std::_Ptr_base<void>::_Resetw<void>(const std::_Ptr_base<void> & _Other) Line 445  C++
    Gnutella.exe!std::weak_ptr<void>::weak_ptr<void><void>(const std::shared_ptr<void> & _Other, void * * __formal) Line 994    C++
    Gnutella.exe!boost::asio::detail::win_iocp_socket_service_base::async_receive<boost::asio::mutable_buffers_1,boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > >(boost::asio::detail::win_iocp_socket_service_base::base_implementation_type & impl, const boost::asio::mutable_buffers_1 & buffers, int flags, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > & handler) Line 292   C++
    Gnutella.exe!boost::asio::stream_socket_service<boost::asio::ip::tcp>::async_receive<boost::asio::mutable_buffers_1,boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > >(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, const boost::asio::mutable_buffers_1 & buffers, int flags, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > && handler) Line 359   C++
    Gnutella.exe!boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >::async_read_some<boost::asio::mutable_buffers_1,boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > >(const boost::asio::mutable_buffers_1 & buffers, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > > && handler) Line 846    C++
    Gnutella.exe!boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > >::operator()(const boost::system::error_code & ec, unsigned int bytes_transferred, int start) Line 273  C++
    Gnutella.exe!boost::asio::async_read<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::mutable_buffers_1,boost::asio::detail::transfer_all_t,boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > >(boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & s, const boost::asio::mutable_buffers_1 & buffers, boost::asio::detail::transfer_all_t completion_condition, boost::_bi::bind_t<void,boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>,boost::_bi::list2<boost::_bi::value<GnutellaApp *>,boost::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > > > > && handler) Line 535   C++
    Gnutella.exe!GnutellaApp::HandleRead(boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & socket) Line 232    C++
>   Gnutella.exe!boost::_mfi::mf1<void,GnutellaApp,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > &>::operator()(GnutellaApp * p, boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & a1) Line 165 C++
    Gnutella.exe!boost::_bi::list2<boost::_bi::value
Это было полезно?

Решение

It would appear as if you are holding a stale reference.

Besides, boost::asio::buffer(buf) is a glaring offense, since buf is a stack-local, but async_read is... well async.

The common patterns are

  • make buf and socket class members (so that they are sure to outlive the async requests)
  • make buf and socket shared (boost::shared_ptr<boost::asio::ip::tcp::socket>) which you can just pass/bind by value:

       boost::bind(&GnutellaApp::HandleRead,
                    this,
                    socket
                 )
    

    would just keep the socket alive as long as the bound function call is kept alive in the io service, by virtue of the shared_ptr

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top