简体   繁体   中英

Boost::Asio::Read is not populating buffer

Here is my server class, which renders an async event to send a string to my client, when connected.

The message is definitely dispatched to the client, as the writehandler is invoked successfully without any errors:

class Server {
private:

    void writeHandler(ServerConnection connection, const boost::system::error_code &error_code,
                      std::size_t bytes_transferred) {

        if (!(error_code)) {
            std::cout << "SENT "<<bytes_transferred <<" BYTES"<< std::endl;
        }
    }

    void renderWriteEvent(ServerConnection connection, const std::string& str) {
        std::cout << "RENDERING WRITE EVENT" << std::endl;
        connection->write = str;
        boost::asio::async_write(connection->socket, boost::asio::buffer(connection->write),
                                 boost::bind(&Server::writeHandler, this, connection,
                                             boost::asio::placeholders::error,
                                             boost::asio::placeholders::bytes_transferred));
    }
    

};

Now on the client side, after successfully connecting to the server, I call

        void renderRead(){
        std::cout<<"Available Bytes: "<<socket.available()<<std::endl;
        std::string foo;


        boost::system::error_code error_code;
        std::size_t x = socket.read_some(boost::asio::buffer(foo), error_code);
        std::cout<<error_code.message()<<std::endl;

        std::cout<<"Bytes read: "<<x<<std::endl;
        std::cout<<"Available Bytes: "<<socket.available()<<std::endl;
        std::cout<<foo<<std::endl;
        //boost::asio::async_read(socket, boost::asio::buffer(read_string), boost::bind(&Client::readHandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
    }

which outputs "Available Bytes: 12"

Then, in calling boost::asio::read , I get 0 bytes read, and no error. I don't understand what's wrong. After the read, the number of bytes available for reading in the socket stream is still printed to be 12

A key point here is that read_some() doesn't allocate any memory, it fills memory that is provided to it. For your code, this means ASIO will only replace the data already existing inside of foo , and it will never exceed these bounds.

But you have std::string foo; , which is a default-constructed string, aka an empty string.

So ASIO is populating the buffer you are passing just fine. However, you are passing it a buffer with no room in it. ASIO fills it as much as possible: 0 bytes.

You can test this for yourself by adding the following to your code:

std::string foo;
std::cout << "Available room in buffer: "<< foo.size() << std::endl;

The fix would be to pass a buffer with memory already allocated. You could initialize the string with a length, but using a raw block of bytes that you interpret later as a string_view is more explicit.

constexpr std::size_t buffer_size = 32;

std::array<char, buffer_size> foo;
std::size_t x = socket.read_some(boost::asio::buffer(foo), error_code);

//...

std::string_view message(foo.data(), x);
std::cout << message << std::endl;


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