Hi Vinnie, Am Di., 3. Sept. 2019 um 16:23 Uhr schrieb Vinnie Falco < vinnie.falco@gmail.com>:
On Tue, Sep 3, 2019 at 7:22 AM Stephan Menzel via Boost-users
wrote: I'm trying to realize an old dream in asio. A function that will take a socket and asynchronously...connect to the result while having a timeout around the operation.
Like this?
< https://www.boost.org/doc/libs/1_71_0/libs/beast/doc/html/beast/ref/boost__b...
Well, not exactly. I wanted to do the resolve and connect in one go. This one has a timeout though, which already is a huge step in the right direction. Didn't know this existed. Anyway, your implementation did bring me to beast::bind_handler, which eventually led me to a working implementation: https://github.com/MrMoose/moose_tools/blob/master/TimedConnect.hpp as it enabled me to adopt the handler to async ops with different handler requirements. However, since I'm here ;-) may I ask a followup in this regard: I have had success with beast::bind_handler using it in timed_connect like this: template <typename Self> void operator()(Self &n_self, const boost::system::error_code &n_error = boost::system::error_code(), boost::asio::ip::tcp::resolver::results_type n_results = boost::asio::ip::tcp::resolver::results_type(), boost::asio::ip::tcp::endpoint n_connected_ep = boost::asio::ip::tcp::endpoint()) { reenter(m_coro) { .... yield boost::asio::async_connect(m_socket, n_results, boost::beast::bind_handler(std::forward<Self>(n_self), boost::placeholders::_1, boost::asio::ip::tcp::resolver::results_type(), boost::placeholders::_2)); .... }} Now, this is great as it was key to have placeholders and therefore combine async ops with incompatible handler types. However, I tried to adopt the exact same thing in my next operation, which shall wrap up a socks4 handshake. Like this template <typename Self> void operator()(Self &n_self, boost::system::error_code n_error = boost::system::error_code(), std::size_t = 0, boost::asio::ip::tcp::resolver::results_type n_results = boost::asio::ip::tcp::resolver::results_type()) { reenter(m_coro) { .... yield m_resolver.async_resolve(tcp::v4(), *m_target_hostname, *m_target_servicename, tcp::resolver::query::numeric_service, boost::beast::bind_handler(std::move(n_self), boost::placeholders::_1, 0, boost::placeholders::_2)); .... }} and in this context, it fails. I have tried many different variations and all I'm getting is crashes in the async_resolve operation that look like moving the handler fails at runtime. Or strange errors at runtime when the op returns with 995, which I suppose means a similar thing, e.g. m_resolver being destroyed Strangely it doesn't seem to matter which op I use the bind_handler with. There is a reolve, a write and a read. Each one will fail weirdly at runtime when I use the bind_handler to adapt the handler type. Of course, I change the signature for operator() for those trials. I strongly suspect it's got something to do with the moving that fails but there's no difference between this object and the one I use in TimedConnect which works great. Here's the data members: boost::asio::ip::tcp::socket &m_socket; boost::asio::ip::tcp::resolver m_resolver; std::unique_ptrstd::string m_target_hostname; boost::uint16_t m_target_port; boost::asio::coroutine m_coro; Nothing that can't be moved.... Anyway, maybe change move errors when using bind_handler rings a bell. Thanks for your suggestions, Stephan