zeromq源码阅读 —— Msg.hpp & Msg.cpp 的 msg_t (zmq中的消息)

因为tcp是一种字节流类型的协议,没有边界,所以把该消息边界的制定留给了应用层。
通常有两种方式实现:
1. 在传统的数据中添加分隔符
2. 在每条消息中添加size字段。

而zeromq采用第2种方案。

zmq_msg_t基本的数据结构
 class msg_t
    {
    public:

        //  Mesage flags. // 表示一些flags
        enum
        {
            more = 1, // 初始值就是00000001
            identity = 64, // 初始值:01000000
            shared = 128   // 初始值:10000000
        };

        bool check ();
        int init ();
        int init_size (size_t size_);
        int init_data (void *data_, size_t size_, msg_free_fn *ffn_,
            void *hint_);
        int init_delimiter ();
        int close ();
        int move (msg_t &src_);
        int copy (msg_t &src_);
        void *data ();
        size_t size ();
        unsigned char flags ();
        void set_flags (unsigned char flags_);
        void reset_flags (unsigned char flags_);
        bool is_identity () const;
        bool is_delimiter ();
        bool is_vsm ();

        //  After calling this function you can copy the message in POD-style
        //  refs_ times. No need to call copy.
        void add_refs (int refs_);

        //  Removes references previously added by add_refs. If the number of
        //  references drops to 0, the message is closed and false is returned.
        bool rm_refs (int refs_);

    private:

        //  Size in bytes of the largest message that is still copied around
        //  rather than being reference-counted.
        enum {max_vsm_size = 29}; // 最大的very small message消息的字节大小,小消息拷贝,非引用计数

        //  Shared message buffer. Message data are either allocated in one
        //  continuous block along with this structure - thus avoiding one
        //  malloc/free pair or they are stored in used-supplied memory.
        //  In the latter case, ffn member stores pointer to the function to be
        //  used to deallocate the data. If the buffer is actually shared (there
        //  are at least 2 references to it) refcount member contains number of
        //  references.
        // 共享的消息buffer。
        struct content_t
        {
            void *data; // 指向真正的消息数据
            size_t size; // 消息数据的字节大小
            msg_free_fn *ffn; // 指向释放函数
            void *hint;      // 传递到回到功能的一个提示值 
            zmq::atomic_counter_t refcnt;// 消息的引用计数
        };

        //  Different message types. // 不同的消息类型
        enum type_t
        {
            type_min = 101,
            type_vsm = 101,
            type_lmsg = 102,
            type_delimiter = 103,
            type_max = 103
        };

        //  Note that fields shared between different message types are not
        //  moved to tha parent class (msg_t). This way we ger tighter packing
        //  of the data. Shared fields can be accessed via 'base' member of
        //  the union.
        union {                                          
            // base                                      
            struct {                                     
                unsigned char unused [max_vsm_size + 1]; 
                unsigned char type;                      
                unsigned char flags;                     
            } base;                                      
            // 针对very small message的小消息做的一些优化,直
            接在stack上分配内存了,可以看后面的消息函数的具体操作
            struct {                                     
                unsigned char data [max_vsm_size]; // 小消息的内存区域
                unsigned char size; // 小消息的大小       
                unsigned char type;                      
                unsigned char flags;                     
            } vsm;                                       
           // 针对大消息                                  
            struct {                                     
                content_t *content; // 指向content_t的结构
                unsigned char unused [max_vsm_size + 1 - sizeof (content_t*)];
                unsigned char type;
                unsigned char flags;
            } lmsg;
           // 定界符                      
            struct {
                unsigned char unused [max_vsm_size + 1];
                unsigned char type;
                unsigned char flags;
            } delimiter;
        } u;
    };
delimiter类型的消息,类似于终结者的意思,主要在收发的管道中使用。

因为zeromq会将消息先发送到管道中,
然后poller运行在另一个线程,将管道中的数据读出来,发往socket的缓冲区,
所以,可以发送一个delimiter类型的消息去终结管道,并销毁它。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值