Boost::Asio::Read未填充缓冲区



这是我的服务器类,它在连接时呈现一个异步事件以向我的客户端发送字符串。

消息肯定会被发送到客户端,因为写入处理程序被成功调用而没有任何错误:

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));
}

};

现在在客户端,在成功连接到服务器后,我调用

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));
}

其输出";可用字节:12〃;

然后,在调用boost::asio::read时,我读取了0个字节,并且没有错误。我不明白怎么了。读取后,套接字流中可供读取的字节数仍打印为12

这里的一个关键点是read_some()不分配任何内存,而是填充提供给它的内存。对于您的代码,这意味着ASIO将只替换foo中已经存在的数据,并且永远不会超过这些界限。

但是您有std::string foo;,它是一个默认构造的字符串,也就是一个字符串。

所以ASIO正在填充你正在传递的缓冲区。然而,你给它传递的是一个没有空间的缓冲区。ASIO尽可能多地填充它:0字节。

您可以通过在代码中添加以下内容来自行测试:

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

修复方法是传递一个已分配内存的缓冲区。可以使用长度初始化字符串,但使用稍后解释为string_view的原始字节块更显式。

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;

最新更新