前言
我所见到最好消息包的接口设计莫过于ACE_Message_Block
了。
为什么这样说呢? 对于它的API说明,我最初仅想在它的基础上提供注释说明,而不想多言其它,因为无需多言其他。
不过,后来还是补充两个图,以利于更友好地说明问题 :)
注释API
Stores messages for use
throughout
ACE (particularly in an ACE_Message_Queue).
是一个整个框架可用的消息类
An ACE_Message_Block is modeled after the message data structures used in System V STREAMS.
系出名门
Its purpose is to enable efficient manipulation of arbitrarily large messages without incurring much
memory copying overhead.
高效的实现,可以轻松应对任意大的消息
Here are the main characteristics of an ACE_Message_Block:
列举下几个主要特性
- Contains a pointer to a reference-counted ACE_Data_Block, which in turn points to the actual data > buffer. This allows very flexible and efficient sharing of data by multiple ACE_Message_Block objects.
支持引用基数等弹性- One or more ACE_Message_Blocks can be linked to form a `‘fragment chain.’’
对于相关性强的消息可以组成分片链表- ACE_Message_Blocks can be linked together in a doubly linked fashion to form a queue of messages (this is how ACE_Message_Queue works).
对于相关性弱一点的消息集合,可以形成列表或队列
基础能力
数据结构一般分为具有连续存储和链表存储,而ACE_Message_Block
两者兼而有之两种能力,无疑增强了它的描述能力!
- 基于wr_ptr、rd_ptr的数组操作能力
- 基于cont指针的紧密相关连续分片chain能力
- 基于pre、next指针链表操作的list、queue能力
- 设置更大size后,内存动态增长的能力
- 可定制化内存管理器的能力
- 支持引用计数的共享使用能力
- 特别地,可定制化内存管理器的能力,与ACE框架的整体能力不无相关,浑然天成
- 在*.inl文件内提供可以inline内联的API,尽量减少封装所带来的overhead,又可以提供参数检查能力
两种存储方式的使用
数组方式
在网络处理报文的惯用法中,通常会对报文正文缓冲区的头尾进行预留空间,以利于对报文进行再次封装或扩展处理,并尽力避免处理网络消息时内存的多次拷贝。对于这种需求,利用ACE_Message_Block
可以轻松实现!
通过移动rd_ptr和wr_ptr可以轻松实现头尾空间预留,以及对消息正文的存储
消息队列
chain链消息意味着消息间的紧相关,例如,网络数据包的分片。chain 消息链能够使用
release
接口进行集中释放,以及使用total*
接口获取消息总长度。
参考
- ACE_Message_Block API