简体   繁体   中英

Boost.Asio, two readings by the same socket

I'm learning Boost.Asio. I have defined a class that has the role of client and server:

  • I can create connections, send requests and receive responses (client role).
  • I can accept requests and send responses to those requests (server role).
  • I can also create subscriptions: Creates a connection, it sends a subscription request and waits for the response. If the remote endpoint accepts the request, it will send me regularly data by this connection.

I want to be able to make requests and receive responses after a subscription, but there is a problem when I get the response: at that moment the socket waiting at the same time receive a subscription and a response.

Sometimes there is deadlock, sometimes I get a subscription when it was waiting for a response, ...

To read, I use the following functions:

void async_receive_subscription(const socket& the_socket, read_handler_signature handler)
{
    auto self( this->shared_from_this() );

    boost::asio::async_read(
        the_socket.get(),
        boost::asio::buffer( my_buffer ),
        [this, self, the_socket, my_buffer, handler]
        ( const boost::system::error_code& error,
          std::size_t bytes_transferred )
        {
            the_socket.get().get_io_service().post(
                std::bind(
                handler,
                error,
                bytes_transferred,
                the_socket,
                my_buffer
                )
            );
            // Read the next subscription.
            async_receive_subscription(the_socket, handler);
        }
    );
}

void async_receive(const socket& the_socket, read_handler_signature handler)
{
    auto self( this->shared_from_this() );

    boost::asio::async_read(
        the_socket.get(),
        boost::asio::buffer( my_buffer ),
        [this, self, the_socket, my_buffer, handler]
        ( const boost::system::error_code& error,
          std::size_t bytes_transferred )
        {
            the_socket.get().get_io_service().post(
                std::bind(
                handler,
                error,
                bytes_transferred,
                the_socket,
                my_buffer
                )
            );
        }
    );
}

Is it possible to expect two responses by the same socket? Is there any synchronization mechanism that can be used to avoid this problem?

Thanks.

async_read is guaranteed to cause exactly one call of the handler.

You must not call async_read again until this handler has been called.

question:

  1. are you running the io_service in multiple threads? If so, you'll need to pass your handler through an asio::strand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM