当前位置: 首页 > news >正文

Qt网络编程-ZMQ的使用

不同主机或者相同主机中不同进程之间可以借助网络通信相互进行数据交互,网络通信实现了进程之间的通信。比如两个进程之间需要借助UDP进行单播通信,则双方需要知道对方的IP和端口,假设两者不在同一主机中,如下示意图:

主机1中的进程A想要与主机2中的进程B进行通信,则首先他们之间需要知道对方所在主机的IP地质以及对方所绑定的端口,好比A和B住在同一个小区(同一个局域网内),A派人给B送信则需要制度B所住的楼栋(主机IP地址)以及B的门牌号(绑定的IP地址)。

不同主机之间的不同进程可以借助网络套接字进行通信,同主机内也是如此,关于进程间通信我之前也写过对应博客:

linux消息队列的简单使用_linux消息队列发送消息为0-CSDN博客

QLocalSocket、QLocalServer实现本地进程通信简单实例_qt vs2015 进程间通信-CSDN博客

这里使用TCP或者UDP进行同一主机内通信也是没有问题的,比如同主机内不同进程使用UDP套接字进行通信,两者可以根据都绑定本机IP127.0.0.1,然后各自根据配置文件绑定不同端口,最后通过QUdpSocket进行数据交互。使用QTcp也是类似,只不过各进程需要指定对应的服务器和客户端,本地进程间通信如果自己实现我还是推进使用QUdpSocket,因为UDP面向报文,无需建立链接,除了单播还可以广播、组播,而且因为处于同一主机,所以基本不用考虑整个报文丢失的问题。第三方库可以采用ZMQ进行进程间通信

第三方库ZeroMQ(也称为ZMQ)是一个流行的消息传递库,它提供了简单而高效的消息传递模式,用于在应用程序之间进行通信。ZeroMQ(ZMQ)可以基于多种传输协议进行通信,包括TCP、UDP、in-process(进程内通信)等。它提供了不同的传输协议来满足不同的通信需求。

ZMQ下载:

The ZeroMQ project · GitHub

下载之后直接解压:

ZMQ编译:

环境:Windows,Qt515.2,VS2022

使用cmake打开:

 

 

完成之后打开对应生成的目录:

使用VS打开对应工程:

编译对应Debug版和release版的库:

 

等待编译完成:

同样方法编译生成Debug版:

生成动态库对应位置:

动态导入库位置:

在工程引入,文件结构:

ZMQ通信主要有REP/REQ、PUB/SUB、PUSH/PULL三种类型,本文主要介绍第二种PUB/SUB即发布/订阅模式 。

工程文件中引入ZMQ头文件以及库文件:

#引入libzmq头文件和库
INCLUDEPATH += $PWD/zmq/includewin32 {LIBS += -L$$PWD/zmq/libCONFIG(release, debug|release) {LIBS += -llibzmq-v143-mt-4_3_6}CONFIG(debug, debug|release) {LIBS += -llibzmq-v143-mt-gd-4_3_6}
}

发布类ZmqPublisher

头文件:

#ifndef ZMQPUBLISHER_H
#define ZMQPUBLISHER_H#include <QObject>class ZmqPublisher : public QObject {Q_OBJECT
public:explicit ZmqPublisher(QObject *parent = nullptr);~ZmqPublisher();bool bind(quint16 port);signals:public slots:void publishData(const QByteArray &data);private:void *context;void *socket;
};#endif // ZMQPUBLISHER_H

源文件:

#include "zmqpublisher.h"
#include "zmq/include/zmq.h"
#include <QDebug>ZmqPublisher::ZmqPublisher(QObject *parent) : QObject{parent} {context = zmq_ctx_new();socket = zmq_socket(context, ZMQ_PUB);
}ZmqPublisher::~ZmqPublisher() {zmq_close(socket);zmq_ctx_destroy(context);
}bool ZmqPublisher::bind(quint16 port) {QString arg = QString("tcp://*:%1").arg(port);int rc = zmq_bind(socket, arg.toUtf8().constData());return rc == 0;
}void ZmqPublisher::publishData(const QByteArray &data) {zmq_send(socket, data, data.size(), 0);
}

订阅类ZmqSubscriber

头文件:

#ifndef ZMQSUBSCRIBER_H
#define ZMQSUBSCRIBER_H#include <QObject>class ZmqSubscriber : public QObject {Q_OBJECT
public:explicit ZmqSubscriber(QObject *parent = nullptr);~ZmqSubscriber();bool connectTo(quint16 port);public slots:void procesMessage();signals:void dataReceived(const QByteArray &data);private:void *context;void *socket;
};#endif // ZMQSUBSCRIBER_H

源文件:

#include "zmqsubscriber.h"
#include "zmq/include/zmq.h"ZmqSubscriber::ZmqSubscriber(QObject *parent) : QObject{parent} {context = zmq_ctx_new();socket = zmq_socket(context, ZMQ_SUB);zmq_setsockopt(socket, ZMQ_SUBSCRIBE, "", 0);
}ZmqSubscriber::~ZmqSubscriber() {zmq_close(socket);zmq_ctx_destroy(context);
}bool ZmqSubscriber::connectTo(quint16 port) {QString arg = QString("tcp://localhost:%1").arg(port);int rc = zmq_connect(socket, arg.toUtf8().constData());return rc == 0;
}void ZmqSubscriber::procesMessage() {while (true) {zmq_msg_t message;zmq_msg_init(&message);zmq_recvmsg(socket, &message, 0);QByteArray data(static_cast<const char *>(zmq_msg_data(&message)),zmq_msg_size(&message));emit dataReceived(data);zmq_msg_close(&message);}
}

调用示例:

新建对应发布类以及线程,将发布类移入线程:

    QThread *m_PubThread;QThread *m_SubThread;ZmqPublisher *m_Publisher;ZmqSubscriber *m_Subscriber;

使用线程调用:

    m_PubThread = new QThread;m_SubThread = new QThread;m_Publisher = new ZmqPublisher;m_Subscriber = new ZmqSubscriber;m_Publisher->moveToThread(m_PubThread);m_Subscriber->moveToThread(m_SubThread);connect(this, &MainWindow::publishData, m_Publisher,&ZmqPublisher::publishData);connect(m_Subscriber, &ZmqSubscriber::dataReceived,[=](const QByteArray &data) {//TODO 处理zmq接收数据});m_PubThread->start();m_SubThread->start();QMetaObject::invokeMethod(m_Subscriber, &ZmqSubscriber::procesMessage);

运行效果:

相关文章:

Qt网络编程-ZMQ的使用

不同主机或者相同主机中不同进程之间可以借助网络通信相互进行数据交互&#xff0c;网络通信实现了进程之间的通信。比如两个进程之间需要借助UDP进行单播通信&#xff0c;则双方需要知道对方的IP和端口&#xff0c;假设两者不在同一主机中&#xff0c;如下示意图&#xff1a; …...

如何清理Docker占用的磁盘空间?

在Docker中&#xff0c;随着时间的推移&#xff0c;占用的磁盘空间可能会不断增加。为了保持系统的稳定性和性能&#xff0c;定期清理Docker占用的磁盘空间非常重要。下面将介绍一些清理Docker磁盘空间的方法。 一、清理无用的容器 有时候&#xff0c;我们可能会运行一些临时…...

从零开始学HCIA之NAT基本工作原理

1、NAT设计之初的目的是解决IP地址不足的问题&#xff0c;慢慢地其作用发展到隐藏内部地址、实现服务器负载均衡、完成端口地址转换等功能。 2、NAT完成将IP报文报头中的IP地址转换为另一个IP地址的过程&#xff0c;主要用于实现内部网络访问外部网络的功能。 3、NAT功能一般…...

Day40- 动态规划part08

一、单词拆分 题目一&#xff1a;139. 单词拆分 139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以…...

论文笔记:相似感知的多模态假新闻检测

整理了RecSys2020 Progressive Layered Extraction : A Novel Multi-Task Learning Model for Personalized Recommendations&#xff09;论文的阅读笔记 背景模型实验 论文地址&#xff1a;SAFE 背景 在此之前&#xff0c;对利用新闻文章中文本信息和视觉信息之间的关系(相似…...

5G技术对物联网的影响

随着数字化转型的加速&#xff0c;5G技术作为通信领域的一次重大革新&#xff0c;正在对物联网&#xff08;IoT&#xff09;产生深远的影响。对于刚入行的朋友们来说&#xff0c;理解5G技术及其对物联网应用的意义&#xff0c;是把握行业发展趋势的关键。 让我们简单了解什么是…...

Nacos1.X源码解读(待完善)

目录 下载源码 注册服务 客户端注册流程 注册接口API 服务端处理注册请求 设计亮点 服务端流程图 下载源码 1. 克隆git地址到本地 # 下载nacos源码 git clone https://github.com/alibaba/nacos.git 2. 切换分支到1.4.7, maven编译(3.5.1) 3. 找到启动类com.alibaba.na…...

算法之双指针系列1

目录 一&#xff1a;双指针的介绍 1&#xff1a;快慢指针 2&#xff1a;对撞指针 二&#xff1a;对撞指针例题讲述 一&#xff1a;双指针的介绍 在做题中常用两种指针&#xff0c;分别为对撞指针与快慢指针。 1&#xff1a;快慢指针 简称为龟兔赛跑算法&#xff0c;它的基…...

苍穹外卖面试题

8. 如何理解分组校验 很多情况下&#xff0c;我们会将校验规则写到实体类中的属性上&#xff0c;而这个实体类有可能作为不同功能方法的参数使用&#xff0c;而不同的功能对象参数对象中属性的要求是不一样的。比如我们在新增和修改一个用户对象时&#xff0c;都会接收User对象…...

【Qt 学习之路】在 Qt 使用 ZeroMQ

文章目录 1、概述2、ZeroMQ介绍2.1、ZeroMQ 是什么2.2、ZeroMQ 主线程与I/O线程2.3、ZeroMQ 4种模型2.4、ZeroMQ 相关地址 3、Qt 使用 ZeroMQ3.1、下载 ZeroMQ3.2、添加 ZeroMQ 库3.3、使用 ZeroMQ3.4、相关 ZeroMQ 案例 1、概述 今天是大年初一&#xff0c;先给大家拜个年&am…...

CI/CD到底是啥?持续集成/持续部署概念解释

前言 大家好&#xff0c;我是chowley&#xff0c;日常工作中&#xff0c;我每天都在接触CI/CD&#xff0c;今天就给出我心中的答案。 在现代软件开发中&#xff0c;持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;和持续部署&#xff08;Continuous D…...

golang常用库之-disintegration/imaging图片操作(生成缩略图)

文章目录 golang常用库之什么是imaging库导入和使用生成缩略图 golang常用库之 什么是imaging库 官网&#xff1a;https://github.com/disintegration/imaging imaging 是一个 Go 语言的图像处理库&#xff0c;它提供了一组功能丰富的函数和方法&#xff0c;用于进行各种图像…...

CSS 控制 video 标签的控制栏组件的显隐

隐藏下载功能 <video src"" controlsList"nodownload" />controlslist 取值如下(设定多个值则使用空格进行间隔) 如&#xff1a;controlslist"nodownload nofullscreen noremoteplayback"nodownload&#xff1a;取消更多控件弹窗的下载功…...

数据可视化之维恩图 Venn diagram

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 维恩图&#xff08;Venn diagram&#xff09;&#xff0c;也叫文氏图或韦恩图&#xff0c;是一种关系型图表&#xff0c;用于显示元素集合之间的重叠区…...

2024刘谦春晚第二个扑克牌魔术

前言 就是刚才看春晚感觉这个很神奇&#xff0c;虽然第一个咱模仿不过来&#xff0c;第二个全国人民这么多人&#xff0c;包括全场观众都有成功&#xff0c;这肯定是不需要什么技术&#xff0c;那我觉得这个肯定就是数学了&#xff0c;于是我就胡乱分析一通。 正文 首先准备…...

【k8s系列】(202402) 证书apiserver_client_certificate_expiration_seconds

apiserver_client_certificate_expiration_second证书定义的位置&#xff1a;kubernetes/staging/src/k8s.io/apiserver/pkg/authentication/request/x509/x509.go at 244fbf94fd736e94071a77a8b7c91d81163249d4 kubernetes/kubernetes (github.com) apiserver_client_certi…...

Rust变量与常量介绍

Rust是一门注重安全性和性能的系统编程语言&#xff0c;其中变量和常量的概念有着独特的设计和特性。在本文中&#xff0c;我们将深入了解Rust中的变量和常量&#xff0c;并解释它们之间的区别&#xff0c;同时通过多个例子进行说明。 Rust常量 在Rust中&#xff0c;常量是不…...

Flask基础学习2

连接mysql数据库测试(专业版) [注意1&#xff1a;要导入text库&#xff0c;否则可能出现找不到select 1错误] [注意2&#xff1a;若出现下列问题&#xff0c;可按照模板代码的顺序db SQLAlchemy(app) 的位置] RuntimeError: Either SQLALCHEMY_DATABASE_URI or SQLALCHEMY_B…...

文章页的上下篇功能是否有必要?boke112百科取消上下篇功能

也不知道是从什么时候开始&#xff0c;我们很多站长的博客网站文章页都会在文末添加上“上一篇”和“下一篇”功能&#xff0c;目的是进行站内SEO优化和方便用户阅读上下篇文章。 boke112百科不管是以前使用的Three主题还是现在使用的YIA主题&#xff0c;刚开始的文章页都是有…...

Lua序列化

我们经常需要序列化一些数据&#xff0c;为了将数据转换为字节流或者字符流&#xff0c;这样我们就可以保存到文件或者通过网络发送出去。我们可以在 Lua 代码中描述序列化的数据&#xff0c;在这种方式下&#xff0c;我们运行读取程序即可从代码中构造出保存的值。 number/st…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...