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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

2024系统分析师考试总结

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

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

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

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 上传的数…

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

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

博途(TIA Portal)自动化工程软件下载安装,TIA Portal V18软件安装包获取

博途&#xff08;TIA Portal&#xff09;不仅仅是一款自动化工程软件&#xff0c;它更是西门子自动化领域的璀璨明珠。 它能够将西门子的所有自动化产品无缝集成在一起&#xff0c;无论是PLC、人机界面&#xff0c;还是伺服系统、马达、变频器、网络组件等&#xff0c;博途都能…

餐饮行业气体泄露风险预警:可燃气体报警器的校准检测策略

在餐饮行业中&#xff0c;使用天然气、液化石油气等可燃气体作为烹饪能源是普遍现象。 然而&#xff0c;气体泄露问题时常威胁着餐饮场所的安全&#xff0c;一旦发生泄露&#xff0c;可能导致火灾、爆炸等严重事故。 因此&#xff0c;为了确保餐饮场所的安全&#xff0c;安装…

文生视频模型Sora刷屏的背后的数据支持

前言&#xff1a;近日&#xff0c;OpenAI的首个文生视频模型Sora横空出世&#xff0c;引发了一波Sora热潮。与其相关的概念股连续多日涨停&#xff0c;多家媒体持续跟踪报道&#xff0c;央视也针对Sora进行了报道&#xff0c;称这是第一个真正意义上的视频生成大模型。 01 …

Rust日常开发三方库精选

日常开发三方库精选 对计算机、编程、架构的理解决定一个程序员的上限&#xff0c;而工具则决定了他的下限&#xff0c;三尺森寒利剑在手&#xff0c;问世间谁敢一战。 本文就分门别类的精心挑选了一些非常适合日常开发使用的三方库&#xff0c;同时针对优缺点、社区活跃等进…

Ubuntu20.04离线安装dpkg

方法一&#xff1a;百度云盘下载离线安装包 链接&#xff1a;https://pan.baidu.com/s/1L7TaFwE35bMfOJbXmJcWwQ 提取码&#xff1a;mjsm --来自百度网盘超级会员V4的分享 方法二&#xff1a;找一台联网计算机&#xff0c;自行下载离线安装包。 1. 创建存放离线包文件夹 …

一次DC9靶机的渗透测试

1.信息收集 2.SQL注入获取用户 3.LFI读取etcpasswd 4.Hydra爆破SSH 5.添加etcpasswd用户提权 1.信息收集&#xff1a; 探测存活主机 nmap -sP 192.168.11.1/24 发现主机探测端口和服务&#xff1a; nmap -sV -p 1-65535 192.168.11.144 2.SQL注入获取用户&#xff1a; HT…

2024年6月29日(星期六)骑行十里箐

2024年6月29日 (星期六&#xff09;骑行十里箐&#xff0c;早8:00到8:30&#xff0c;大观公园门口集合&#xff0c;9:00准时出发【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点:大观公园门口集合 &#xff0c;家住东&#xff0c;南&#xff0c;北…

如何在前端项目中制定代码注释规范

本文是前端代码规范系列文章&#xff0c;将涵盖前端领域各方面规范整理&#xff0c;其他完整文章可前往主页查阅~ 开始之前&#xff0c;介绍一下​最近很火的开源技术&#xff0c;低代码。 作为一种软件开发技术逐渐进入了人们的视角里&#xff0c;它利用自身独特的优势占领市…

四步轻松搞定!探索字节最新AnimateDiff-Lightning:高质量视频生成的秘密武器!

字节前脚刚发布了文生图大模型 SDXL-Lightning&#xff0c;后脚就又对文生视频领域下手了。 就在这几天又推出了文生视频模型&#xff1a;AnimateDiff-Lightning&#xff0c;它是一种快速的文本到视频生成模型。它生成视频的速度比原始 AnimateDiff 快十倍以上&#xff0c;只需…