ZMQ请求应答模型

案例一

这个案例的出处是ZMQ的官网。请求段发送Hello,应答端回复World。
ZMQ

Request(client)

#include <string>
#include <iostream>
#include <zmq.hpp>

using namespace std;
using namespace zmq; // 使用 zmq 命名空间

int main()
{
    // initialize the zmq context with a single IO thread
    context_t context{1};

    // construct a REQ (request) socket and connect to interface
    socket_t socket{context, socket_type::req};
    socket.connect("tcp://localhost:5555");

    // set up some static data to send
    const string data{"Hello"};

    for (auto request_num = 0; request_num < 10; ++request_num) 
    {
        // send the request message
        cout << "Sending Hello " << request_num << "..." << endl;
        socket.send(buffer(data), send_flags::none);
        
        // wait for reply from server
        message_t reply{};
        socket.recv(reply, recv_flags::none);

        cout << "Received " << reply.to_string(); 
        cout << " (" << request_num << ")";
        cout << endl;
    }

    return 0;
}

Reply(server)

#include <string>
#include <chrono>
#include <thread>
#include <iostream>

#include <zmq.hpp>

int main() 
{
    using namespace std::chrono_literals;

    // initialize the zmq context with a single IO thread
    zmq::context_t context{1};

    // construct a REP (reply) socket and bind to interface
    zmq::socket_t socket{context, zmq::socket_type::rep};
    socket.bind("tcp://*:5555");

    // prepare some static data for responses
    const std::string data{"World"};

    for (;;) 
    {
        zmq::message_t request;

        // receive a request from client
        socket.recv(request, zmq::recv_flags::none);
        std::cout << "Received " << request.to_string() << std::endl;

        // simulate work
        std::this_thread::sleep_for(1s);

        // send the reply to the client
        socket.send(zmq::buffer(data), zmq::send_flags::none);
    }

    return 0;
}

编译

g++ -o server server.cpp `pkg-config --cflags --libs libzmq`
g++ -o client client.cpp `pkg-config --cflags --libs libzmq`

在这里插入图片描述

请求应答步骤

请求端

建立与应答端的连接

第一步:创建ZMQ上下文
context_t context{1};

创建一个 ZeroMQ 上下文(context),并初始化为只有一个 I/O 线程。context_t 是 ZeroMQ 库中用于管理套接字的类。

第二步:创建一个请求套接字
socket_t socket{context, socket_type::req}

在上下文中创建一个套接字(socket),并指定其类型为 req(请求者)。这意味着这个套接字将发送请求并等待响应。

第三步:连接端点
socket.connect("tcp://localhost:5555")

将套接字连接到本地主机上的 5555 端口。这是服务器监听的端口。

发送消息请求

发送消息不是固定的,可以用静态字符串发送,也可以输入信息发送,但用socket发送消息的函数是不变的。

socket.send()

用于发送消息

socket.send(buffer(data), send_flags::none);
函数参数
buffer(data)

这是一个 zmq::buffer 对象,它是一个辅助类,用于创建一个消息缓冲区。在这里,它接收一个 std::string 类型的参数 data,并将这个字符串的内容作为消息发送。buffer 类型的对象通常用于封装消息数据,以便与 ZeroMQ 的套接字接口一起使用。

send_flags

这是一个枚举值,用于指定发送消息时的选项。send_flags::none 表示没有特殊的发送标志,即消息将按照默认的方式发送。ZeroMQ 还提供了其他发送标志,例如:

send_flags::dontwait:非阻塞发送,如果无法立即发送消息,函数会立即返回,而不是等待。
send_flags::sndmore:表示消息分多部分发送,这个标志用于告诉 ZeroMQ 还有更多的消息部分即将发送。

函数返回值

在 ZeroMQ 的 C++ 绑定中,socket.send() 函数的返回值是一个整数,表示发送的字节数。这个返回值通常用于确认消息是否成功发送,以及发送了多少数据。
如果发送成功,函数返回发送的字节数。如果发送失败,函数返回 -1,并设置相应的错误代码,可以通过 errno 来获取。

接收应答端的回复

message_t

这个message_t也是ZMQ库中的类,reply也就是类的对象

message_t reply{};

创建一个 message_t 类型的变量 reply,用于接收服务器的响应。

socket.recv();
socket.recv(reply, recv_flags::none);

从服务器接收响应消息,并将消息内容存储在 reply 变量中。

函数参数
reply

这是一个 zmq::message_t 类型的对象,它用于存储从套接字接收到的消息。zmq::message_t 是 ZeroMQ 库中用于表示消息的类。当 recv 函数成功执行后,reply 对象将包含接收到的消息数据。

recv_flags::none:

这是一个枚举值,用于指定接收消息时的选项。recv_flags::none 表示没有特殊的接收标志,即消息将按照默认的方式接收。ZeroMQ 还提供了其他接收标志,例如:

recv_flags::dontwait:非阻塞接收,如果当前没有消息可接收,函数会立即返回,而不是等待。
recv_flags::recvmore:告诉 ZeroMQ 预期更多的消息部分将会到来。这通常用于多部分消息的接收。

函数返回值

在 ZeroMQ 的 C++ 绑定中,socket.recv() 函数的返回值是一个布尔值,表示是否成功接收到了消息。这个返回值用于判断接收操作是否成功完成。

如果返回 true,表示成功接收到了消息,并且 zmq::message_t 对象(如示例中的 reply)中包含了接收到的消息数据。
如果返回 false,表示接收操作失败。失败的原因可能是因为套接字被关闭、发生了错误,或者(如果使用了非阻塞标志)没有消息可接收。

应答端

建立与端点的连接

第一步:创建ZMQ上下文
context_t context{1};

创建一个 ZeroMQ 上下文(context),并初始化为只有一个 I/O 线程。context_t 是 ZeroMQ 库中用于管理套接字的类。

第二步:创建一个请求套接字
socket_t socket{context, socket_type::rep};

在上下文中创建一个套接字(socket),并指定其类型为 rep(应答者)。这意味着这个套接字将等待请求消息并响应回复。

第三步:连接端点
socket.bind("tcp://*:5555");

将套接字连接到本地主机上的 5555 端口。这是服务器的端口。

接收请求端的请求消息

message_t

这个message_t也是ZMQ库中的类,reply也就是类的对象

message_t request;

创建一个 message_t 类型的变量 request,用于接收请求端的消息。

socket.recv();
socket.recv(request, recv_flags::none);

从服务器接收响应消息,并将消息内容存储在 request变量中。

处理请求消息,应答请求

socket.send()

用于发送消息

socket.send(buffer(data), send_flags::none);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP轻创推客集淘客地推任务平台于一体的综合营销平台系统源码

&#x1f680;轻创推客&#xff0c;营销新纪元 —— 集淘客与地推任务于一体的全能平台&#x1f310; &#x1f308;【开篇&#xff1a;营销新潮流&#xff0c;轻创推客引领未来】 在瞬息万变的营销世界里&#xff0c;你还在为寻找高效、全面的营销渠道而烦恼吗&#xff1f;&…

【STM32】C语言基础补充

学习过程中发现自己好些需要用到的C语言语法、特征都不太熟练了&#xff0c;特意记录一下&#xff0c;免得忘记了&#xff0c;以后遇到了新的也会继续更新 目录 1 全局变量 2 结构体 3 静态变量 4 memset()函数 5 使用8位的存储器存16位的数 1 全局变量…

汽车冷却液温度传感器

1、冷却液温度传感器的功能 发动机冷却液温度传感器&#xff0c;也称为ECT&#xff0c;是帮助保护发动机&#xff0c;提高发动机工作效率以及帮助发动机稳定运行的非常重要的传感器之一。 发动机冷却液温度 &#xff08;ECT&#xff09; 传感器用于测量发动机的冷却液温度&…

Vue项目创建和使用

快速上手 | Vue.js (vuejs.org) nodejs.org/ vue项目实质上是index.html页面和多个js文件的集合&#xff0c;最终解析后的html和js代码可以由浏览器解析运行&#xff1a; vue项目的创建&#xff0c;需要脚手架工具来搭建&#xff1b; 在编译的源码阶段&#xff0c;文件格式为.…

集团数字化转型方案(十二)

集团数字化转型方案致力于通过构建一个集成化的数字平台&#xff0c;全面应用大数据分析、人工智能、云计算和物联网等前沿技术&#xff0c;推动业务流程、管理模式和决策机制的全面升级。该方案将从业务流程的数字化改造开始&#xff0c;优化资源配置&#xff0c;提升运营效率…

MySQL的源码安装及基本部署(基于RHEL7.9)

这里源码安装mysql的5.7.44版本 一、源码安装 1.下载并解压mysql , 进入目录: wget https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-5.7.44.tar.gz tar xf mysql-boost-5.7.44.tar.gz cd mysql-5.7.44/ 2.准备好mysql编译安装依赖: yum install cmake g…

牛客网习题——通过C++实现

一、目标 实现下面4道练习题增强C代码能力。 1.求123...n_牛客题霸_牛客网 (nowcoder.com) 2.计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com) 3.日期差值_牛客题霸_牛客网 (nowcoder.com) 4.打印日期_牛客题霸_牛客网 (nowcoder.com) 二、对目标的实现 1.求123...n_…

杰发科技AC7840——CAN通信简介(8)_通过波特率和时钟计算SEG_1/SEG_2/SJW/PRESC

通过公式计算 * 波特率和采样点计算公式&#xff1a;* tSeg1 (S_SEG_1 2); tSeg2 (S_SEG_2 1).* BandRate (SCR_CLK / (S_PRESC 1) / ((S_SEG_1 2) (S_SEG_2 1))), SCR_CLK 为CAN 模块源时钟* SamplePoint (tSeg1 / (tSeg1 tSeg2)). {0x0D, 0x04, 0x04, 0x3B},…

[创业之路-140] :生产 - 生产流程概述

目录 前言&#xff1a; 一、生产流程的基本框架 二、生产流程的关键要素 前言&#xff1a; 生产流程是一个广泛的概念&#xff0c;它涵盖了从原材料投入到成品产出的全过程。 这个过程在不同行业和领域中有所不同&#xff0c;但通常都包括一系列有序的步骤和环节。 以下是…

WIN 10 添加右键菜单(VSCode 打开当前目录)

WIN 10 添加右键菜单&#xff08;VSCode 打开当前目录&#xff09; 前言最终效果操作步骤 前言 每次打开代码都需要先打开 VSCode&#xff0c;再选择最近打开的项目或者浏览打开项目&#xff0c;感觉比较难找。所以自己添加了右键命令。 最终效果 操作步骤 cmd 打开注册表 找…

C语言程序设计(初识C语言后部分)

十七&#xff0c;数组 1.一维数组的创建和初始化 1&#xff09;数组的创建 数组是一组相同类型元素的集合 数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组大小 …

R语言统计分析——回归分析的改进措施

参考资料&#xff1a;R语言实战【第2版】 如果在回归诊断中发现了问题&#xff0c;我们该如何做&#xff1f;有四种方法可以处理违背回归假设的问题&#xff1a; ①删除观测点&#xff1b; ②变量变换&#xff1b; ③添加或删除变量&#xff1b; ④使用其他回归方法。 1、…

C语言 ——— 常见的动态内存错误(下篇)

目录 使用free释放一块动态开辟内存的一部分 对同一块动态内存多次释放 动态开辟内存忘记释放&#xff08;内存泄漏&#xff09; 使用free释放一块动态开辟内存的一部分 代码演示&#xff1a; // 动态开辟10个整型空间 int* p (int*)malloc(sizeof(int) * 10);// 判断是…

Pod基础使用

POD基本操作 1.Pod生命周期 在Kubernetes中&#xff0c;Pod的生命周期经历了几个重要的阶段。下面是Pod生命周期的详细介绍&#xff1a; Pending&#xff08;待处理&#xff09;: 调度: Pod被创建后&#xff0c;首先进入“Pending”状态。此时&#xff0c;Kubernetes的调度器…

机器视觉运动控制一体机VPLC532E在汽车胶带缠绕的开放式CNC应用

市场应用背景 在汽车线束和零配件中&#xff0c;胶带缠绕是一种常见且重要的加工工艺&#xff0c;主要用于线束/零配件的捆扎、固定、绝缘保护等应用。在缠绕头控制下&#xff0c;胶带均匀缠绕在汽车线束/零配件表面&#xff0c;完成缠绕后&#xff0c;系统自动执行切割。汽车…

【CSS】使用 CSS 自定义属性(变量)-- var()

自定义属性&#xff08;有时候也被称作CSS 变量或者级联变量&#xff09;是由 CSS 作者定义的&#xff0c;它包含的值可以在整个文档中重复使用。由自定义属性标记设定值&#xff08;比如&#xff1a; --main-color: black;&#xff09;&#xff0c;由 var() 函数来获取值&…

qtsql连接达梦数据库

odbc window和linux都有odbc的中间件&#xff0c;可以通过odbc中间件配合qtsql连接数据库 windows下配置odbc linux配置odbc apt install unixodbc unixodbc-dev /etc/odbcinst.ini配置 [DM8 ODBC DRIVER] DescriptionDM8 ODBC Driver DRIVER/opt/dmdbms/bin/libdodbc.so/et…

安装打印机提示“打印后台程序服务没有启动”的解决方法

1、在桌面选中“我的电脑”&#xff0c;鼠标右键选择“管理”&#xff1b; 2、在“管理”窗口中&#xff0c;选取“服务和应用程序”扩展项目下的“服务”选项&#xff08;如图&#xff09;&#xff0c;在右侧出现系统服务列表中找到“Print Spooler”服务&#xff0c;双击进入…

JavaWeb基础 -- Servlet

JavaWeb基础 – Servlet 1.Servlet简介 1.1 Servlet是什么 Servlet本身是用Java编写的&#xff0c;运行在Web服务器上的应用程序&#xff0c;并作为Web浏览器和其他HTTP客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。Servlet可以收集来自网页表单输入的数据…

ARM 裸机与 Linux 驱动对比及 Linux 内核入门

目录 ARM裸机代码和驱动的区别 Linux系统组成 内核五大功能 设备驱动分类 内核类型 驱动模块 驱动模块示例 Makefile配置 命令 编码辅助工具 内核中的打印函数 printk 函数 修改打印级别 ​编辑 打印级别含义 驱动多文件编译 示例 模块传递参数 命令行传递参数…