ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – boost :: asio :: buffer:获取缓冲区大小并防止缓冲区溢出?

2019-10-04 14:14:53  阅读:837  来源: 互联网

标签:buffer-overflow c boost-asio


我有以下两个用于发送和接收数据包的功能.

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的情况下检查缓冲区的大小?另一个问题是如何防止缓冲区溢出?

解决方法:

要获得缓冲区的大小,可以使用boost::asio::buffer_size()函数.但是,在您的示例中,这很可能对您没用.

如缓冲区overview中所述,Boost.Asio使用缓冲区类来表示缓冲区.这些类提供抽象并保护Boost.Asio操作免受缓冲区溢出的影响.虽然boost :: asio :: buffer()的结果被传递给操作,但是不传输元数据,例如缓冲区的大小或其底层类型.此外,这些缓冲区不拥有内存,因此应用程序有责任确保底层内存在缓冲区抽象的生命周期内保持有效.

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

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

>通过socket::available()查询套接字可用的数据量,然后相应地分配缓冲区.

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

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

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

>正如Öö Tiib所示,将长度作为通信协议的一部分.有关通信协议的示例,请查看Boost.Asio examples.专注于协议,不一定在Boost.Asio API上.

>在固定大小的协议中,数据生产者和消费者都使用相同大小的消息.当读者知道消息的大小时,读者可以提前分配缓冲区.
>在可变长度协议中,消息通常分为两部分:标题和正文.标题通常是固定大小,并且可以包含各种元信息,例如正文的长度.这允许读者将标题读入固定大小的缓冲区,提取体长,为身体分配缓冲区,然后读取体.

// 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.    

标签:buffer-overflow,c,boost-asio
来源: https://codeday.me/bug/20191004/1853284.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有