• C++操作ZEROMQ


    ZMQ介绍

    1. 性能极高的通信框架

    2. 吞吐量大,延迟低

    一.zmq

    1. zmq_ctx_new()

      创建zmq的上下文。记得释放资源。

      std::shared_ptr _context(zmq_ctx_new(), [](void* p) 
      { 
        if(p)
            zmq_ctx_destroy(p);
      });

    2. zmq_socket()

      利用创建的上下文构建一个socket。记得释放资源。

      //发布者
      std::shared_ptr _publisher(zmq_socket(_context.get(), ZMQ_PUB), [](void* p) 
      { if (p)
          zmq_close(p); 
      });
      //订阅者
      std::shared_ptr _subscriber(zmq_socket(_context.get(), ZMQ_SUB), [](void* p) 
      { if (p)
          zmq_close(p); 
      });
    3. zmq_bind()

      利用创建的socket绑定通信的地址,无需释放。

      //发布者绑定端口
      zmq_bind(_publisher.get(), "tcp://*:5555")
      //接收者连接端口
      int ret = zmq_connect(_subscriber.get(), "tcp://localhost:5555");
      assert(ret == 0);
    4. zmq_send()

      数据帧:在实际应用中,我们几乎不会发送简单的基本数据类型,发送的内容都是以结构体的形式存在的,我们管这种结构体叫做数据帧。数据帧例子定义如下:

      typedef struct Person{
          int num;
          int age;
          char * name;  
      }
      Person person;
      person.num=1506100061;
      person.age=25;
      person->name="xiaoyu";
      //发布者首先发送数据到自己的缓冲队列里面
      zmq_send(_publisher.get(),&person,sizeof(person),0);

      5.zmq_recv()

      //
      ret = zmq_setsockopt(_subscriber.get(), ZMQ_SUBSCRIBE, "", 0);
      assert(ret == 0);
      //订阅者阻塞等待接收者的信息
      Person person;//数据帧
      ret = zmq_recv(_subscriber.get(), &person, sizeof(Person), 0);
      if(ret>0){
          //do something
      }

      6.CMakeLists.txt编写

      cmake_minimum_required(VERSION 3.0.2)
      ​
      project(zmq_test)
      ​
      add_compile_options(-std=c++11)
      #修改为自己的目录
      include_directories(
          include
          third/zmq-4.3.4/include
          ${CMAKE_CURRENT_SOURCE_DIR}
      )
      #修改为自己的目录
      link_directories(
          third/zmq-4.3.4/lib
      )
      #修改为自己的目录
      add_executable(sender src/send.cpp)
      #修改为自己的目录
      add_executable(recver src/recv.cpp)
      #修改为自己的目录
      link_libraries(third/zmq-4.3.4/lib/libzmq.a)
      ​
      target_link_libraries(sender zmq)
      ​
      target_link_libraries(recver zmq)
      ​
      ​

    二. zmq_msg_xxx()

    1. zmq_msg_t

      zmq使用的是zmq_msg_t来表示消息,而不是使用普通的数据块char *,string等类型来交换数据,所以你需要创建一个zmq_msg_t对象。

      zmq_msg_t zmsg;

    2. zmq_msg_init()

      可以使用zmq_msg_init()来初始化一个zmq_msg_t对象,然后传递给zmq_msg_recv

      zmq_msg_init(&zmsg)
    3. zmq_msg_recv()

      等待消息发送方,并把接受到的消息放到zmq_msg_t对象里面保存

      std::shared_ptr _context(zmq_ctx_new(), 
      [](void* p) { 
          if (p)
              zmq_ctx_destroy(p); 
      });
      std::shared_ptr _in(zmq_socket(_context.get(), ZMQ_PULL),
       [](void* p) {
           if (p)
               zmq_close(p); 
       });
      zmq_msg_recv(&zmsg,_in,0)//第三个参数0代表的是什么意思?

      补充C 库函数 memcpy()的用法:

      void *memcpy(void *str1, const void *str2, size_t n)

      从存储区 str2 复制 n 个字节到存储区 str1

      该函数返回一个指向目标存储区 str1 的指针

      //实例
      #include 
      #include 
      
      int main ()
      {
      const char src[50] = "http://www.runoob.com";
      char dest[50];
      
      memcpy(dest, src, strlen(src)+1);//+1是把字符串最后一个结束符'\0'也复制过去
      printf("dest = %s\n", dest);
      
      return(0);
      }
    4. zmq_msg_data()

      要访问消息内容,可以使用zmq_msg_data()

      (char *)zmq_msg_data(&zmsg) //可以强制转换为字符串类型,然后打印输出

    5. zmq_msg_close()

      要释放消息,则调用zmq_msg_close(),这会删除一个引用,当消息引用为0时,ØMQ会最终自动帮你销毁该消息

      zmq_msg_close(&zmsg);
  • 相关阅读:
    Sentinel 熔断与限流
    工作经验总结之 Eslint 报错和开发技巧。
    HTTP,HTTPS,WebSocket协议辨析
    Spring Boot 开启https访问(配置SSL证书)
    说透缓存一致性与内存屏障
    【Spring boot 集成 Fliter 和 Linstener】
    空间几何(点线面)知识整理
    Image Animation是什么
    easyexecl导出100万行execl报字体错误的解决办法
    @DateTimeFormat 和 @JsonFormat 注解详解
  • 原文地址:https://blog.csdn.net/weixin_40327259/article/details/126101893