助推asio HTTP服务器,如何停止

boost asio http server, how to stop?

本文关键字:何停止 服务器 asio HTTP 助推      更新时间:2023-10-16

我正在使用boost附带的示例http服务器之一(在doc/html/boost_asio/example/cpp03/http/server,或者在http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.http_server)。

示例打开一个接收套接字并进行侦听,剥离请求对象的请求。服务器还有一个boost asio signal_set,当收到SIGINT或SIGTERM时,它会注册信号处理程序并取消io_service内的所有asio请求。按CTRL-C接收信号,io_service调用handle_stop()函数,然后在所有asio::ip::tcp::sockets上调用.close()。整个服务器正常关闭,io_service.run()调用退出,程序结束。

我希望能够在一个线程中启动这个http服务器,然后以编程方式取消它,而不是使用信号。公认的做法是什么?我删除了signal_set和信号处理程序,然后在另一个线程上启动服务器。它可以很好地处理来自新线程的http请求。我如何阻止它从另一个线程?从不同的线程调用asio::ip::tcp::socket::close()是安全的吗?文档是不清楚的,这样做感觉非常,不像亚洲。事实上,当我尝试这样做时,只要我还没有接受任何http请求,它就能很好地工作。如果我只处理了一个http请求,那么这个进程就会在boost中崩溃:

>   test_ssl_server_sa.exe!boost::detail::sp_counted_base::add_ref_lock()  Line 81 + 0x3 bytes  C++
    test_ssl_server_sa.exe!boost::detail::shared_count::shared_count(const boost::detail::weak_count & r={...})  Line 578 + 0x12 bytes  C++
    test_ssl_server_sa.exe!boost::shared_ptr<http::server::connection>::shared_ptr<http::server::connection><http::server::connection>(const boost::weak_ptr<http::server::connection> & r={...})  Line 405 + 0x3f bytes    C++
    test_ssl_server_sa.exe!boost::enable_shared_from_this<http::server::connection>::shared_from_this()  Line 49 + 0xc bytes    C++
    test_ssl_server_sa.exe!http::server::connection::handle_handshake(const boost::system::error_code & error={...})  Line 83 + 0x11 bytes  C++
    test_ssl_server_sa.exe!boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>::operator()(http::server::connection * p=0x004b8fe8, const boost::system::error_code & a1={...})  Line 165 + 0x18 bytes    C++
    test_ssl_server_sa.exe!boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> >::operator()<boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list1<boost::system::error_code const &> >(boost::_bi::type<void> __formal={...}, boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &> & f={...}, boost::_bi::list1<boost::system::error_code const &> & a={...}, boost::_bi::type<void> __formal={...})  Line 314    C++
    test_ssl_server_sa.exe!boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > >::operator()<boost::system::error_code>(const boost::system::error_code & a1={...})  Line 48  C++
    test_ssl_server_sa.exe!boost::asio::ssl::detail::handshake_op::call_handler<boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > & handler={...}, const boost::system::error_code & ec={...}, const unsigned int & __formal=0)  Line 55    C++
    test_ssl_server_sa.exe!boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >::operator()(boost::system::error_code ec={...}, unsigned int bytes_transferred=0, int start=0)  Line 276   C++
    test_ssl_server_sa.exe!boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>::operator()()  Line 129   C++
    test_ssl_server_sa.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, ...)  Line 70 C++
    test_ssl_server_sa.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > & context={...})  Line 37 + 0x16 bytes   C++
    test_ssl_server_sa.exe!boost::asio::ssl::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > * this_handler=0x00fefb70)  Line 319 + 0x10 bytes  C++
    test_ssl_server_sa.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int>,boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > >(boost::asio::detail::binder2<boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > >,boost::system::error_code,unsigned int> & function={...}, boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > & context={...})  Line 37 + 0x16 bytes   C++
    test_ssl_server_sa.exe!boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1,boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ssl::detail::handshake_op,boost::_bi::bind_t<void,boost::_mfi::mf1<void,http::server::connection,boost::system::error_code const &>,boost::_bi::list2<boost::_bi::value<http::server::connection *>,boost::arg<1> > > > >::do_complete(boost::asio::detail::task_io_service * owner=0x00c1aca0, boost::asio::detail::task_io_service_operation * base=0x00c1f948, const boost::system::error_code & __formal={...}, const boost::system::error_code & __formal={...})  Line 110 + 0xd bytes    C++
    test_ssl_server_sa.exe!boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service & owner={...}, const boost::system::error_code & ec={...}, unsigned int bytes_transferred=0)  Line 38 + 0x1a bytes C++
    test_ssl_server_sa.exe!boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::win_mutex> & lock={...}, boost::asio::detail::task_io_service_thread_info & this_thread={...}, const boost::system::error_code & ec={...})  Line 386  C++
    test_ssl_server_sa.exe!boost::asio::detail::task_io_service::run(boost::system::error_code & ec={...})  Line 153 + 0x1e bytes   C++

我并不是说服务器可能没有不同的同步问题-特别是,它看起来像服务器在boost::shared_ptr上对连接对象进行多次访问而崩溃。但我更感兴趣的是,从另一个线程关闭asio io_service.run()调用的正确方法是什么。当我想象我希望如何工作时,我想象一个等待控制变量的io_service请求。如果我想关闭服务器,我将从另一个线程向控制变量发出信号,io_service将在io_service线程上调用我的回调。从那里,它可以.close()任何套接字或以其他方式取消任何其他正在运行的请求。

您可以使用boost::asio::io_service::post与试图停止http服务器的线程的lambda。lambda将在http服务器线程中执行。它可以安全地在所有套接字上调用socket::close。这将优雅地停止服务