c++进程间通信--zeromq

ZeroMQ(也写作 ØMQ、0MQ 或 zmq)是一个高性能的异步消息队列库,提供了一种灵活的方式来实现进程间通信(IPC)以及网络通信。在C++中使用ZeroMQ进行进程间通信非常直观和高效。zmq的通信模式如下:

下面先说明请求响应模式的特点和建立过程。

1.特点

REQ-REP模式是一种同步的、基于请求-响应的通信方式,适用于需要明确请求和响应的场景,比如RPC(远程过程调用)。

2.建立过程

请求响应模式(Request-Reply Pattern)是ZeroMQ提供的一个基本通信模式,用于实现客户端与服务器之间的同步交互,其中客户端发送请求并等待服务器的响应。下面是该模式的详细工作过程:

2.1. 初始化套接字

服务器端(REP):创建并绑定一个ZMQ_REP类型的套接字到一个指定的地址(可以是TCP端口或IPC路径)。

void *context = zmq_ctx_new();
void *socket = zmq_socket(context, ZMQ_REP);
int rc = zmq_bind(socket, "tcp://*:5555"); // 绑定到端口555

客户端(REQ):创建并连接一个ZMQ_REQ类型的套接字到服务器的地址。

void *context = zmq_ctx_new();
void *socket = zmq_socket(context, ZMQ_REQ);
int rc = zmq_connect(socket, "tcp://localhost:5555"); // 连接到服务器的5555端口

2.2. 请求发送和响应接收

客户端(REQ):

发送请求:客户端通过zmq_send()发送一个请求消息到服务器。

zmq_send(socket, "Request Data", strlen("Request Data"), 0);

等待响应:客户端调用zmq_recv()阻塞等待服务器的响应。

char buffer[1024];
zmq_recv(socket, buffer, 1024, 0);
std::cout << "Received: " << buffer << std::endl;

服务器端(REP)

接收请求:服务器通过zmq_recv()阻塞等待客户端的请求。

char buffer[1024];
zmq_recv(socket, buffer, 1024, 0);
std::cout << "Received Request: " << buffer << std::endl;

处理请求并发送响应:服服务器处理请求后,通过zmq_send()发送响应消息给客户端。

zmq_send(socket, "Response Data", strlen("Response Data"), 0);

3.顺序和匹配

ZeroMQ确保请求与响应的顺序对应,即客户端发送的每个请求都将对应于从服务器接收的下一个响应。

4.几点说明

  • 同步性:请求响应模式是同步的,客户端在接收到响应前会阻塞。

  • REP套接字行为:服务器的REP套接字在发送完响应后会自动进入等待下一个请求的状态,不允许连续发送两个响应而没有收到新的请求。

  • 错误处理:如果任何一方关闭连接,另一方在尝试读写时可能会遇到错误,需要适当处理。

5.完整sample

5.1 linux zmq安装:

sudo apt-get install libzmq3-dev
sudo apt-get install czmq-dev
git clone https://github.com/zeromq/cppzmq.git
cd cppzmq
mkdir build && cd build
cmake ..
make
sudo make install

5.2 服务器

#include <zmq.hpp>
#include <iostream>
#include <string>int main() {zmq::context_t context(1);zmq::socket_t socket(context, ZMQ_REP);socket.bind("tcp://*:5555");while (true) {zmq::message_t request;socket.recv(&request);std::string request_str = std::string(static_cast<char*>(request.data()), request.size());std::cout << "Received request: " << request_str << std::endl;std::string response = "Response: " + request_str;zmq::message_t reply(response.size());memcpy((void*)reply.data(), response.c_str(), response.size());socket.send(reply);}return 0;
}

5.3 客户端

#include <zmq.hpp>
#include <iostream>
#include <string>int main() {zmq::context_t context(1);zmq::socket_t socket(context, ZMQ_REQ);socket.connect("tcp://localhost:5555");for (int request_nbr = 0; request_nbr != 5; ++request_nbr) {zmq::message_t request(std::to_string(request_nbr));socket.send(request, ZMQ_NOBLOCK);zmq::message_t reply;socket.recv(&reply);std::string reply_str = std::string(static_cast<char*>(reply.data()), reply.size());std::cout << "Received reply " << request_nbr << ": " << reply_str << std::endl;}return 0;
}

需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

下面说明下zmq发布订阅方式的建立过程。

1.发布订阅模式

ZeroMQ的发布订阅(Pub-Sub)模式是一种一对多的消息传递模式,适用于消息广播场景。在这个模式中,一个或多个发布者(Publisher)发送消息到特定的主题上,而一个或多个订阅者(Subscriber)可以选择订阅这些主题以接收消息。

2.发布订阅模式建立过程

2.1. 初始化Context

在ZeroMQ中,所有的套接字都关联到一个唯一的上下文(Context)。首先,创建一个上下文对象:

#include <zmq.hpp>zmq::context_t context(1); // 参数1表示Io线程的数量,默认为1

2.2. 创建并配置发布者套接字

发布者创建一个ZMQ_PUB类型的套接字,并将其绑定到一个地址。这个地址可以是TCP端口或IPC通道,允许订阅者连接。

zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind("tcp://*:5555"); // 绑定到所有可用IP的5555端口
// 或使用IPC
// publisher.bind("ipc:///tmp/pubsub.ipc");

2.3. 创建并配置订阅者套接字

  • 订阅者创建一个ZMQ_SUB类型的套接字,并连接到发布者的地址。

  • 订阅者还需要订阅至少一个主题,如果不订阅任何主题,默认情况下不会接收到任何消息。主题可以是空字符串,表示订阅所有主题。

zmq::socket_t subscriber(context, ZMQ_SUB);
subscriber.connect("tcp://localhost:5555"); // 连接到发布者的5555端口
// 或使用IPC
// subscriber.connect("ipc:///tmp/pubsub.ipc");// 订阅主题,这里订阅名为"weather"的主题
subscriber.setsockopt(ZMQ_SUBSCRIBE, "weather", strlen("weather"));
// 若要订阅所有主题,可以设置空字符串
// subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);

2.4.发布消息

发布者通过zmq_send()或相应的ZeroMQ API发送消息到一个主题。消息由主题和数据组成,主题通常是消息的前缀。

std::string topic = "weather";
std::string data = "It's sunny today.";
zmq::message_t msg(data.size());
memcpy(msg.data(), data.data(), data.size());
publisher.send(msg, ZMQ_SNDMORE); // 发送主题
publisher.send(topic);

注意:在某些版本的ZeroMQ中,可能需要手动拼接主题和消息内容,或者使用特定的API来一次性发送带有主题的消息。

2.5.接收消息

订阅者使用zmq_recv()或相应的API接收消息。ZeroMQ会自动过滤掉未订阅主题的消息。

zmq::message_t received;
subscriber.recv(&received);
std::string receivedData(reinterpret_cast<char*>(received.data()), received.size());
std::cout << "Received: " << receivedData << std::endl;

3.总结

发布订阅模式在ZeroMQ中的建立过程涉及创建上下文、发布者和订阅者套接字,绑定和连接到指定的地址,设置订阅主题,以及发送和接收消息。这种模式支持动态添加和移除订阅者,且发布者无需了解订阅者的具体信息,提高了系统的可扩展性和灵活性。附录:完整Demo

发布者

#include <zmq.hpp>
#include <iostream>
#include <string>
#include <unistd.h> // for sleepint main() {zmq::context_t context(1);zmq::socket_t publisher(context, ZMQ_PUB);publisher.bind("tcp://*:5555"); // 绑定到所有可用IP的5555端口std::cout << "Publisher is up and running..." << std::endl;while (true) {std::string message = "Current temperature: 22 C";std::string topic = "weather";// 发布消息,ZeroMQ不直接支持在消息前加主题,需手动拼接zmq::message_t msg(topic.size() + message.size() + 1); // +1是为了添加分隔符memcpy(msg.data(), topic.data(), topic.size());memcpy(static_cast<char*>(msg.data()) + topic.size() + 1, message.data(), message.size()); // +1跳过分隔符位置publisher.send(msg, ZMQ_DONTWAIT);std::cout << "Sent: " << message << std::endl;usleep(1000000); // 每秒发送一次}return 0;
}

订阅者

#include <zmq.hpp>
#include <iostream>
#include <string>int main() {zmq::context_t context(1);zmq::socket_t subscriber(context, ZMQ_SUB);subscriber.connect("tcp://localhost:5555"); // 连接到发布者的5555端口subscriber.setsockopt(ZMQ_SUBSCRIBE, "weather", 7); // 订阅主题"weather"std::cout << "Subscriber is connected and subscribed to 'weather'." << std::endl;while (true) {zmq::message_t message;subscriber.recv(&message);// 假设消息格式为 主题+分隔符+内容,这里直接处理消息内容std::string received = std::string(static_cast<char*>(message.data()));std::cout << "Received: " << received.substr(8) << std::endl; // 去掉前8个字符("weather ")}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/35425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

保护你的代码堡垒:精通npm audit命令

保护你的代码堡垒&#xff1a;精通npm audit命令 在当今快速发展的软件开发领域&#xff0c;安全漏洞如同暗夜中的刺客&#xff0c;随时可能对我们的应用程序发起致命一击。幸运的是&#xff0c;npm提供了一个强大的安全审计工具——npm audit命令&#xff0c;它能帮我们检测和…

第 11 课:组件介绍与自定义开发

本讲主要介绍了隐语的组件标准、已有的组件能力以及进一步的自定义开发流程。经过本讲的学习&#xff0c;可以为将隐语集成到任意调度系统&#xff0c;基于Kusica/SecretPad进行二次开发&#xff0c;以及参与隐语开放标准共建建立基础。 一、隐语开放标准 隐语提出的适用于隐私…

2024.06.26【读书笔记】|医疗科技创新流程(前言)【AI增强版】

目录 《BIODESIGN》第二版前言详细总结前言概述新增重要内容价值导向 (Value Orientation)全球视角 (Global Perspectives)更好的教学和学习方法 (Better Ways to Teach and Learn)全新视频集合 (New Videos)扩展的“实地”案例研究 (Expanded “From the Field” Case Studies…

产品3D展示有哪些优势?3D能替代2D展示吗?

随着科技的飞速发展和经济的持续增长&#xff0c;我们见证了一个从2D到3D的产品展示革命。与传统的2D图片展示相比&#xff0c;3D产品展示正以其独特的优势逐渐崭露头角。 一、3D产品展示的独特优势 1、更逼真的视觉效果&#xff1a; 3D展示技术能够以更为真实、立体的方式展…

证件照制作工具有哪些?这6个帮你自制证件照

许多人可能认为&#xff0c;制作一张符合标准要求的证件照&#xff0c;必须亲自前往照相馆。 然而&#xff0c;事实上&#xff0c;我们完全可以使用手机或电脑上的证件照制作app&#xff0c;自己轻松完成证件照的制作。无论是更换背景颜色&#xff0c;还是调整照片尺寸&#x…

qt qml-http之XMLHttpRequest介绍详解使用

文章目录 QML中的XMLHttpRequest详解与示例基本用法示例代码代码详解更复杂的示例:POST请求代码详解结论QML中的XMLHttpRequest详解与示例 XMLHttpRequest 是 QML 中用于执行HTTP请求的一种机制,类似于Web中的AJAX。它可以用来进行异步的数据传输,可以从服务器获取数据,也…

【ARM】Ulink不同的系列对于芯片的支持和可以支持keil软件

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 了解不同版本的ULINK可以支持的芯片架构&#xff0c;和ULINK可以和哪个系列的keil软件进行在线调试 2、 问题场景 用于了解不同ULINK仿真器对于芯片的支持是不一样的&#xff0c;并不是ULINK可以支持所有的keil软件…

typescript 枚举类型

枚举类型 枚举类型是为数不多的特有类型之一&#xff0c;它允许开发者定义一组命名常量&#xff0c;这些常量可以是数字或字符串类型。枚举类型提供了一种方式来组织和管理一组相关的值&#xff0c;使得代码更加清晰和易于理解。 数字枚举类型 enum Direction1 {Up 1, //初…

1. ansible作用、部署

ansible作用、部署 一、ansible介绍1、ansible特性 二、ansible安装部署1、建议配置ssh免密2、安装ansible3、配置主机清单文件 /etc/ansible/hosts3.1 未分组的写法3.2 分组的写法 4、添加非免密的主机 一、ansible介绍 基于python语言开发的&#xff0c;自动化运维工具 作用…

2024系统分析师考试总结

考试缘由 我自己在毕业不久就考过了中级的软件设计师&#xff0c;这几年换到外企后事情不多&#xff0c;今年初定计划的时候就想着不如考个系统分析师吧。为什么选这个类别呢&#xff1f;按道理我主做程序开发&#xff0c;如果去考系统架构师通过率可能会大一些&#xff0c;但…

【Uniapp微信小程序】图片左右分割/分割线切割图片/图片批量分割线切割

特别说明:本文章因业务组件功能,不完全开放/暂vip可见,有需要者留言找博主! ps:注意!!本效果为图片分割切割!!不是文档切割!!图片仅供参考! 效果图 父组件 / 上传图片页面(index) 写一个上传按钮即可,事件方法: uni.chooseMessageFile({extension: [".j…

kylin v10 系统 rpm安装常见问题

libprofiler.so.0()(64bit) is needed by nginx-1:1.16.1-2.ky10.aarch64 安装gperftools-libs gperftools-libs-2.6.1-1.el7.i686 : Libraries provided by gperftools Repo : base Matched from: Provides : libprofiler.so.0libjpeg-devel 安装libjpeg-turbo-d…

Unity | Shader基础知识(第十六集:简单的全息扫描效果)

目录 一、前言 二、准备模型 三、 场景准备 四、代码准备 五、透明度设置 六、补充介绍 1.Pass语法介绍 2.ColorMask 七、作者的碎碎念 一、前言 这节课的内容是接着弧形边缘光的效果之后做的。 Unity | Shader基础知识(第十四集&#xff1a;简单效果练习)_unity shade…

idea或vscode支持vue语法,ts可解析*.vue

一、ide不能解析vue文件 刚开始导入时&#xff0c;在vscode中的vue文件中内容都是灰色的 ide不能解析vue解决方法&#xff1a; 1.idea或webstorm安装vue.js插件 2.在vscode中 vue2.0的项目安装vetur插件vue3.0及以上的项目安装Vue-official插件&#xff08;之前是Volar&…

PC XMind v24 解锁版安装教程 (全球领先的商业思维导图软件)

前言 XMind 是一款专业的全球领先的商业思维导图软件&#xff0c;在国内使用广泛&#xff0c;拥有强大的功能、包括思维管理、商务演示、与办公软件协同工作等功能。它采用全球先进的Eclipse RCP软件架构&#xff0c;是集思维导图与头脑风暴于一体的可视化思考工具&#xff0c…

mysql GROUP_CONCAT分组连接

文章目录 GROUP_CONCAT 分组连接GROUP_CANCAT 的使用分班级列出名单分班级列出名单并包含显示性别组合IFNULL组合IF组合case when GROUP_CONCAT 分组连接 准备的数据示例 CREATE TABLE students (id int(11) NOT NULL AUTO_INCREMENT,name varchar(20) DEFAULT NULL,classNa…

Rust监控可观测性

可观测性 在监控章节的引言中&#xff0c;我们提到了老板、前端、后端眼中的监控是各不相同的&#xff0c;那么有没有办法将监控模型进行抽象、统一呢&#xff1f; 来简单分析一下&#xff1a; 业务指标实时展示&#xff0c;这是一个指标型的数据( metric )手机 APP 上传的数…

Karabiner-Elements 设置mac键盘

软件下载地址&#xff1a; Karabiner-Elements 修改键盘位置&#xff0c;但是重启后&#xff0c;就消失了。 {"description": "New Rule (change left_shiftcaps_lock to page_down, right_shiftcaps_lock to left_commandmission_control)","manip…

Python下三方库pyttsx3让你的文本读出来(Win10环境)

一、三方库pyttsx3简介&#xff1a; pyttsx3是一个文本到语音转换的Python库&#xff0c;能够跨平台工作在Windows、MacOS和Linux系统上。这个库的一个显著特点是它不依赖于网络连接&#xff0c;因为它使用了系统自带的语音引擎。pyttsx3支持多种语音属性&#xff0c;包括语速…

Android简介-历史、API等级与体系结构

1. Android简介 Android是一种基于Linux内核的自由及开放源代码的操作系统。最初是由安迪鲁宾(Andy Rubin)开发的一款相机操作系统。2005年8月被Google收购。2007年11月&#xff0c;Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。…