加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSS
您当前的位置: > 论文 > 英语论文

详解Beast:是什么意思、发音、用法及记忆方法

时间:2026-03-01 09:12:33  来源:网络整理  作者:佚名

【注】Beast是Boost中关于http(s)/websocket(s)的库,首发于boost 1.66(2016年),是比较新的库,它主要包含了http、websocket协议的解析(反序列化)和封装(序列化)以及关于网络的操作,它以asio为基础,但似乎又想隔离Asio。本文不是关于beast的全面描述,只涉及一些要点贝语网校,主要资料来源于beast官方文档和实现代码。本文对应boost 的版本为1.73。

一、Beast中的Buffer1.概念

软件程序中,缓存区是被广泛应用的概念。Beast中的缓存区大多来自于Asio,DynamicBuffer是指由大小可变的缓存区域,根据不同内存方式,有三种形态:

BufferSequence其实是一个容器起步网校,将若干内存类包装起来(一般用双向链表),本身只提供遍历操作就可以了,它又分为可写的MutableBufferSequence和只读的ConstBufferSequence。MutableBufferSequence用于接收过程(即从网络接收到字节流,写入缓存),ConstBufferSequence可用于发送过程(即读出缓存区中已生成的字节流,发送到网络)。

Asio实现了两个“轻量级”的内存区域定义const_buffer和mutable_buffer,其实就是对struct {const void *, size_t }和struct {void *, size_t }这样结构的封装,内存的分配与释放由使用者负责,const_buffer和mutable_buffer只是引用而已,个人猜想实际的应用场景太多样了,如果将更多的功能添加到buffer上,来构造一个“重量级”的缓存管理,会影响性能,这与基础库的宗旨是不符的,因此Asio中只有一个streambuf类。

作为偏应用级别的Beast,其中有不少关于buffer的类,它进行了较大扩展,但意味着牺牲了性能和灵活性。个人感觉有点过头了,实际应用有各种要求,一致化的读写方式,显得比较繁琐,还是留给应用比较好。

以下是beast涉及缓存的类和辅助类。

2.flat_buffer

flat_buffer的定义如下:

using flat_buffer = basic_flat_buffer< std::allocator< char > >;

就是basic_flat_buffer的一个特化。

flat_buffer就相当于一个装内容的容器,外部写入的内容,对容器来说,就是读入的内容,外部写入区域可mutable,确认(commit)之后,就变成读入区的末尾,并且是只读的(const),在外部消费(consume)之后,清理读入区。

在flat_buffer内部实现时,采用了begin_,in_,out_,last_,end_五个指针来管理内存分配和各区域的大小一流范文网,如下图所示。

beast是什么意思  beast的发音  beast的用法  beast怎么记_Beast flat_buffer multi_buffer_Beast Buffer DynamicBuffer

要注意的是,单纯设置max_size不会引起内存的重新分配,只有在确实需要时才会,因此,Prepre, shrink_to_fit可能会重新分配内存。每次commit,consume,clear之后,会有相关指针的移动,因此建议从flat_buffer得到的读入或写入区域的指针,应即得即用,不要缓存,除非确认读入/写入区不会发生变化。

以下是一个flat_buffer的示例。

	boost::beast::flat_buffer buffer(100);
	buffer.max_size(200);
	auto buf=buffer.prepare(10);       // buffer.prepare(201)会引发异常
	char* const p = static_cast(buf.data());
	memcpy(p, "123456", 6);
	buffer.commit(6);
	auto cbuf = buffer.cdata();
	char temp[10];
	memcpy(temp, cbuf.data(), buffer.size());
	for (int i = 0; i < buffer.size(); ++i)  printf("[%c]", temp[i]); printf("n");

上例中,先设定一个100字节的buffer,然后调整大小为200(此时并不重新分配,但会在后续操作中如此),如果申请(prepare)201大小的区域,则会产生异常。申请10字节大小写入区域,然后写入6个字符,最后查看读入区域,输出上述6个字符。输出如下:

3.multi_buffer

multi_buffer的定义如下:

using multi_buffer = basic_multi_buffer< std::allocator< char > >;

就是basic_multi_buffer的一个特化。

multi_buffer从功能上讲与flat_buffer是一样的,区别在于内存管理模式。flat_buffer的内存是一块连续区域(大小在运行时按需而变)钓鱼网,multi_buffer的内存是一系列块(每块大小可以不相同),multi_buffer采用boost:: Intrusive库中的双向链表来管理,从整体上看,multi_buffer内存变得不连续了,操作上就麻烦多了,好处是不会发生内存大小调整了。

以下是一个multi_buffer的示例。

	boost::beast::multi_buffer mbuffer(10);
	auto buf1 = mbuffer.prepare(6);
	for (auto it : buf1)
	{
		printf("writable:[%u]n", it.size());
		memset(it.data(),'a', it.size());
	}
	mbuffer.commit(6);
	mbuffer.max_size(30);
	auto buf2 = mbuffer.prepare(7);
	for (auto it : buf2)
	{
		printf("writable:[%u]n", it.size());
		memset(it.data(),'A', it.size());
	}
	mbuffer.commit(7);
	auto bufs = mbuffer.data();
	size_t aa=bufs.buffer_bytes();
	printf("totalsize:%un",aa);
	char temp[100];
	for(auto it : bufs)  
	{
		memcpy(temp, it.data(), it.size());
		for (int i = 0; i < it.size(); ++i)  printf("[%c]", temp[i]); printf("n");
	}

上例中物业经理人,先设定一个10字节的buffer,此时会有一个10字节的内存块,写入(提交)6字节,然后再将buffer增大到30,则会有两个内存块(大小分别为10和(30-10),此时并不分配,但会变得如此),第二次写入(提交)7字节,其中4个字节写入第一块,3个字节写入第二块,最后将写入的内容打印出来,运行输出如下:

beast是什么意思  beast的发音  beast的用法  beast怎么记_Beast Buffer DynamicBuffer_Beast flat_buffer multi_buffer

4.flat_static_buffer

flat_static_buffer的定义如下:

template< std::size_t N>
class flat_static_buffer : public flat_static_buffer_base

flat_static_buffer可认为是max_size在编译时就已确定的flat_buffer,因此内存大小固定,不会发生重新分配。基类flat_static_buffer_base引用外部分配的内存,定义了一系列操作,flat_static_buffer则分配了一段内存,其操作方法与基类基本一致(多了base()和operator=)。

以下是一个使用示例,与上面的示例基本一样。

boost::beast::flat_static_buffer<10> buf;
boost::asio::mutable_buffer  aa = buf.prepare(3);
memcpy(aa.data(), "aa", aa.size());
buf.commit(aa.size());
printf("capcity=%d read=%dn", buf.capacity(),buf.size());
boost::asio::const_buffer  bb = buf.data();
printf("%s[%d]n", static_cast(bb.data()), bb.size());
buf.consume(aa.size());
printf("capcity=%d read=%dn", buf.capacity(), buf.size());

输出为:

来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
推荐资讯
相关文章
栏目更新
栏目热门