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.