c++socketsboost-asioreusability

How can I reuse a boost::asio socket, received from acceptor.async_accept call in coroutine environement?


I'm new to Boost::Asio and have encountered a problem with asio::ip::tcp::socket storage. I receive a server side socket from an asio::ip::tcp::acceptor.async_accept() call and store it in allocated memory. Then, when I initiate the socket.async_send() call, nothing happens: no action, no errors. If the socket is in global memory everything works fine. What should I do? Here is my (pseudo) code:

// Connecting coro
asio::awaitable<void> run_server(asio::io_context &context) // contex is globally allocated
{
        asio::ip::tcp::acceptor acceptor(context, asio::ip::tcp::endpoint{asio::ip::make_address_v4(p_joinserver->get_ip_addr()), p_joinserver->get_port()});
        while (true)
        {
// Preliminary create a soket and place it into unordered map            
auto psocket = std::make_shared<socket_t>(context);
            auto handle = std::rand();
            auto [iter, res] = p_server->connections.emplace(std::make_pair(handle,psocket)); 

            *psocket = co_await acceptor.async_accept(asio::use_awaitable); // Works OK

            asio::co_spawn(context, read_requests(handle), asio::detached);
        }
}

// Receiving and sending coro
asio::awaitable<void> read_requests(int handle)
{

    constexpr size_t buf_size = 1024;
    std::string line(buf_size, '\0');


        while (true)
        {
            auto psocket = p_server->connections.at(handle);
  
            auto n_read = co_await psocket->async_read_some(
                asio::buffer(line),
                asio::use_awaitable); // Works OK
// <> 
//..prepare sending
            auto _psocket = p_server->connections.at(handle);
            auto n_sent = co_await _psocket->async_send(
                 asio::buffer(line),
                 asio::use_awaitable); // Does nothing and throw no error 
    }
}


Solution

  • I am very grateful to @stephen for the useful approch, he suggested, but he did not answer the main question, which I may have phrased inaccurately:

    How one can keep sockets, initialised with different connections for use in coroutines to be called later?

    The working answer: I should have used another form of async_accept, for example:

    `p_connection = std::make_shared<connection_t>(context /*,<constructor args>*/); co_await acceptor.async_accept(p_connection->socket, asio::use_awaitable);`