mardi 12 juin 2018

Asio async_read_until reads old data

I am using Boost.Asio to manage TCP connections on server side.

I know that async_read_until can read beyond the delimiter. My problem is that I sometimes read old data, by which I mean data which I have already received but which has not been sent again.

Consider this code:

#define MAX_RECV_BYTES 512;
boost::asio::streambuf buffer;
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket;

void startReading()
{

    buffer.prepare(MAX_RECV_BYTES);
    boost::asio::async_read_until(socket, buffer, "(EOF)",
                                  boost::bind(&readHandler,
                                              boost::asio::placeholders::error,
                                              boost::asio::placeholders::bytes_transferred
                                              ));

}

void readHandler(const boost::system::error_code& error, size_t bytes_transferred)
{

    if(!error)
    {
        buffer.commit(bytes_transferred);

        std::string message((std::istreambuf_iterator<char>(buffer)), std::istreambuf_iterator<char>());
        std::cout << "Received message: " << message << std::endl;

        buffer.consume(bytes_transferred);

        buffer.prepare(MAX_RECV_BYTES);
        boost::asio::async_read_until(socket, buffer, "(EOF)",
                                      boost::bind(&readHandler,
                                                  boost::asio::placeholders::error,
                                                  boost::asio::placeholders::bytes_transferred
                                                  ));


    }
}

After a connection with a client has been successfully established, startReading() is called.

Now comes the problem. Sometimes old data is read in readHandler. For example, a client sends two messages:

  1. dog(EOF)
  2. cat(EOF)

When the first message is received, readHandler prints

Received message: dog(EOF)

When the second message is received, a part from the old data is read again:

Received message: cat(EOF)og(EOF)

I feel like this has something to do with the way I am handling the streambuf.

Aucun commentaire:

Enregistrer un commentaire