boost :: asio :: buffer:获取缓冲区大小并防止缓冲区溢出? [英] boost::asio::buffer: Getting the buffer size and preventing buffer overflow?

查看:1801
本文介绍了boost :: asio :: buffer:获取缓冲区大小并防止缓冲区溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下两个函数用于发送和接收数据包。

I have the two following functions for sending and receiving packets.

void send(std::string protocol)
{
    char *request=new char[protocol.size()+1];
    request[protocol.size()] = 0;
    memcpy(request,protocol.c_str(),protocol.size());

    request_length = std::strlen(request);
    boost::asio::write(s, boost::asio::buffer(request, request_length));
}
void receive()
{
    char reply[max_length];
    size_t reply_length = boost::asio::read(s, boost::asio::buffer(reply, request_length));
    std::cout << "Reply is: ";
    std::cout.write(reply, reply_length);
    std::cout << "\n";
}

问题与此部分有关 boost :: asio :: buffer(reply,request_length)其中请求长度是在发送数据包时最初设置的字符串的长度。如何在不知道 request_length 的情况下检查缓冲区的大小?另一个问题是如何防止缓冲区溢出?

The questions pertain to this part boost::asio::buffer(reply, request_length) where the request length is the length of a string which was initially setup when the packet was sent. How do I check the size of the buffer without knowing request_length? Another question is how do I prevent buffer overflow?

推荐答案

要获取缓冲区的大小, boost :: asio :: buffer_size() 功能可以使用。但是,在您的示例中,这很可能对您没有什么用处。

To get the size of a buffer, the boost::asio::buffer_size() function can be used. However, in your example, this will most likely be of little use to you.

如缓冲区概述,Boost.Asio使用缓冲区类来表示缓冲区。这些类提供了针对缓冲区溢出的抽象和保护Boost.Asio操作。虽然 boost :: asio :: buffer()的结果被传递给操作,但是元数据(例如缓冲区的大小或其基础类型)不是发送。此外,这些缓冲区不拥有内存,因此应用程序负责确保底层内存在缓冲区提取生命周期内保持有效。

As explained in the buffer overview, Boost.Asio use buffer classes to represent buffers. These classes provide an abstraction and protect Boost.Asio operations against buffer overruns. Although the result of boost::asio::buffer() is passed to operations, the meta-data, such as the size of the buffer or its underlying type, is not transmitted. Also, these buffers do not own the memory, so it is the applications responsibility to ensure the underlying memory remains valid throughout the duration of the buffer abstraction's lifetime.

boost :: asio :: buffer()函数提供了一种方便的方法来创建缓冲区类,其中缓冲区的大小从可能的类型中推导出来。当Boost.Asio能够推导出缓冲区长度时,Boost.Asio操作不会在使用生成的缓冲区类型时调用缓冲区溢出。但是,如果应用程序代码将缓冲区的大小指定为 boost :: asio :: buffer(),则应用程序负责确保大小不大于比底层内存。

The boost::asio::buffer() function provides a convenient way to create the buffer classes, where the size of the buffer is deduced from the type possible. When Boost.Asio is able to deduce the buffer length, then Boost.Asio operations will not invoke a buffer overflow when using the resulting buffer type. However, if the application code specifies the size of the buffer to boost::asio::buffer(), then it is the applications responsibility to ensure that the size is not larger than the underlying memory.

读取数据时,需要缓冲区。基本问题变成如何知道如何分配多少内存,如果Boost.Asio不传输大小。有这个问题的几个解决方案:

When reading data, a buffer is required. The fundamental question becomes how does one know how much memory to allocate, if Boost.Asio does not transmit the size. There are a few solutions to this problem:

  • Query the socket for how much data is available via socket::available(), then allocate the buffer accordingly.

std::vector<char> data(socket_.available());
boost::asio::read(socket_, boost::asio::buffer(data));


  • 使用Boost.Asio可以在内存中增长的类,例如 boost :: asio :: streambuf 。某些操作,例如 boost :: asio :: read() 接受 streambuf 对象作为它们的缓冲区,并按操作所需分配内存。然而,应提供完成条件;否则,操作将继续,直到缓冲区已满。

  • Use a class that Boost.Asio can grow in memory, such as boost::asio::streambuf. Some operations, such as boost::asio::read() accept streambuf objects as their buffer and will allocate memory as is required for the operation. However, a completion condition should be provided; otherwise, the operation will continue until the buffer is full.

    boost::asio::streambuf data;
    boost::asio::read(socket_, data,
                      boost::asio::transfer_at_least(socket_.available()));
    


  • 由于ÖöTiib 建议,将长度作为通信协议的一部分。有关通讯协议的示例,请查看Boost.Asio 示例。专注于协议,不一定是Boost.Asio API

  • As Öö Tiib suggests, incorporate length as part of the communication protocol. Check the Boost.Asio examples for examples of communication protocols. Focus on the protocol, not necessarily on the Boost.Asio API.


    • 在固定大小的协议中,数据生产者和消费者使用相同大小的邮件。由于读者知道消息的大小,因此读者可以预先分配缓冲区。

    • 在可变长度协议中,消息通常分为两部分:和身体。头部通常是固定大小的,并且可以包含各种元信息,例如主体的长度。这允许读取器将头部读取到固定大小的缓冲器中,提取身体长度,为身体分配缓冲器,然后读取身体。

    • In a fixed size protocol, both the data producer and consumer use the same size message. As the reader knows the size of the message, the reader can allocate a buffer in advance.
    • In a variable length protocol, the messages are often divided into two parts: a header and a body. The header is normally fixed size, and can contain various meta-information, such as the length of the body. This allows a reader to read a header into a fixed size buffer, extract the body length, allocate a buffer for the body, then read the body.

    // Read fixed header.
    std::vector<char> data(fixed_header_size);
    boost::asio::read(socket_, boost::asio::buffer(data));
    
    protocol::header header(data);
    network_to_local(header); // Handle endianess.
    
    // Read body.
    data.resize(header.body_length());
    boost::asio::read(socket_, boost::asio::buffer(data));  
    
    protocol::body body(data);
    network_to_local(body); // Handle endianess.    
    


  • 这篇关于boost :: asio :: buffer:获取缓冲区大小并防止缓冲区溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆