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);

运行效果:

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

第4章——深度学习入门(鱼书)

第4章 神经网络的学习 本章的主题是神经网络的学习。这里所说的“学习”是指从训练数据中自动获取最优权重参数的过程。本章中&#xff0c;为了使神经网络能进行学习&#xff0c;将导入损失函数这一指标。而学习的目的就是以该损失函数为基准&#xff0c;找出能使它的值达到最…

C++中类的6个默认成员函数【构造函数】 【析构函数】

文章目录 前言构造函数构造函数的概念构造函数的特性 析构函数 前言 在学习C我们必须要掌握的6个默认成员函数&#xff0c;接下来本文讲解2个默认成员函数 构造函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c…

动态内存经典笔试题分析

1.代码1 void GetMemory(char *p) { p (char *)malloc(100); } void Test(void) { char *str NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); } int main&#xff08;&#xff09; { Test&#xff08;&#xff09;&#xff1b; return 0&#x…

Qlik Sense : Lookup函数

LookUp - 脚本函数 Lookup() 用于查找已经加载的表格&#xff0c;并返回与在字段 match_field_name 中第一次出现的值 match_field_value 对应的 field_name 值。表格可以是当前表格或之前加载的其他表格。 语法&#xff1a; lookup(field_name, match_field_name, match_…

2024牛客寒假算法基础集训营3

前言 感觉有些题是有难度&#xff0c;但是是我花时间想能想的出来的题目&#xff0c;总体来说做的很爽&#xff0c;题目也不错。个人总结了几个做题技巧&#xff0c;也算是提醒自己。 1.多分类讨论 2.从特殊到一般&#xff0c;便于找规律。例如有一组数&#xff0c;有奇数和…

[word] word自定义编号格式怎么设置 #经验分享#职场发展#职场发展

word自定义编号格式怎么设置 在Word文档的编辑中&#xff0c;经常会给段落添加编号&#xff0c;但是在编号的使用过程中我们会遇到很多问题&#xff0c;今天给大家分享word自定义编号格式怎么设置&#xff0c;希望能帮到您&#xff01; 1.如何自定义编号格式&#xff1f; 点击…

【第二十三课】最小生成树:prime 和 kruskal 算法(acwing858,859 / c++代码 )

目录 前言 Prime算法--加点法 acwing-858 代码如下 一些解释 Kruskal算法--加边法 acwing-859 并查集与克鲁斯卡尔求最小生成树 代码如下 一些解释 前言 之前学最短路的时候&#xff0c;我们都是以有向图为基础的&#xff0c;当时我们提到如果是无向图&#xf…

Java基础深度剖析:从数据类型到新特性一揽无余

Java基础深度剖析&#xff1a;从数据类型到新特性一揽无余 Java 基础一、数据类型基本类型包装类型缓存池 二、String概览不可变的好处String, StringBuffer and StringBuilderString Poolnew String("abc") 三、运算参数传递float 与 double隐式类型转换switch 四、…

百度PaddleOCR字符识别推理部署(C++)

1 环境 1.opencv&#xff08;https://sourceforge.net/projects/opencvlibrary/&#xff09; 2.cmake&#xff08;https://cmake.org/download/&#xff09; 3.vs2019&#xff08;(https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1) 4.paddleOCR项目-建议2.0(http…

数据结构第十四天(树的存储/双亲表示法)

目录 前言 概述 接口&#xff1a; 源码&#xff1a; 测试函数&#xff1a; 运行结果&#xff1a; 往期精彩内容 前言 孩子&#xff0c;一定要记得你的父母啊&#xff01;&#xff01;&#xff01; 哈哈&#xff0c;今天开始学习树结构中的双亲表示法&#xff0c;让孩…

Nginx实战:1-安装搭建

目录 前言 一、yum安装 二、编译安装 1.下载安装包 2.解压 3.生成makefile文件 4.编译 5.安装执行 6.执行命令软连接 7.Nginx命令 前言 nginx的安装有两种方式&#xff1a; 1、yum安装&#xff1a;安装快速&#xff0c;但是无法在安装的时候带上想要的第三方包 2、…

第二十七回 武松威镇安平寨 施恩义夺快活林-人人爱用的Python编程语言

张青提议武松不要去牢城营受苦&#xff0c;可以把公差杀掉然后去二龙山入伙鲁智深。武松却坚持他的道义原则&#xff0c;不愿意伤害一路上照顾他的两位公人。张青尊重他的决定&#xff0c;救醒了两位公人。 张青、孙二娘和武松以及两位公人一起喝酒吃饭&#xff0c;张青还向武…

大数据Flume--入门

文章目录 FlumeFlume 定义Flume 基础架构AgentSourceSinkChannelEvent Flume 安装部署安装地址安装部署 Flume 入门案例监控端口数据官方案例实时监控单个追加文件实时监控目录下多个新文件实时监控目录下的多个追加文件 Flume Flume 定义 Flume 是 Cloudera 提供的一个高可用…

幻兽帕鲁服务器怎么更新?进入游戏显示:加入的比赛正在运行不兼容的版本,请尝试升级游戏版本(阿里云)

幻兽帕鲁服务器怎么更新&#xff1f;进入游戏显示&#xff1a;加入的比赛正在运行不兼容的版本&#xff0c;请尝试升级游戏版本。这是因为游戏客户端或者服务器上的游戏服务端&#xff0c;没有更新版本。导致两个版本不一致&#xff0c;所以无法进入游戏。 最近幻兽帕鲁 官方客…

15.3 Redis入门(❤❤❤❤)

15.3 Redis入门❤❤❤❤ 1. redis简介与配置1.1 简介1.2 Windows安装1.3 Linux安装1.4 守护进程方式启动1.5 客户端启动与使用1.6 指定生成日志 2. 使用2.1 客户端redis使用命令2.2 redis存储的数据类型1. String字符串类型2. Hash键值类型3. List列表类型4. Set与Zset集合类型…

问题:超声波纵波斜入射时,当入射角大于第一临界角小于第二临界角时,在第二介质内只有折射横波。 #微信#经验分享#其他

问题&#xff1a;超声波纵波斜入射时&#xff0c;当入射角大于第一临界角小于第二临界角时&#xff0c;在第二介质内只有折射横波。 参考答案如图所示

面向对象编程:理解其核心概念与应用

引言 在编程的世界中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;已成为一种主流的编程范式。它提供了一种组织和管理代码的有效方式&#xff0c;使得代码更加模块化、可重用和易于维护。本文将带您深入探讨面向对象编程的核心概念及其…

波奇学Linux:文件重定向和虚拟文件系统

重定向 文件描述符所对应的分配规则&#xff0c;从0开始&#xff0c;寻找最小没有使用的数组位置。 如图所示&#xff0c;关闭文件描述符的0&#xff0c;新打开的文件描述符为0&#xff0c;而关闭2&#xff0c;文件描述符为2。 重定向&#xff1a;文件输出的对象发生改变 例…

网络协议、网络传输认识

目录 网络协议概念 网络协议具象化理解 协议分层 TCP/IP模型 网络传输基本流程 网络协议概念 网络协议是计算机网络中用于在通信设备之间传输数据的规则集合。这些规则定义了数据的格式、传输方式、错误检测和纠正方法等&#xff0c;以确保不同设备之间的通信能够正确进行…

计算机网络之一

目录 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网 1.2.因特网发展的三个阶段 1.3基于ISP的三层架构的因特网 1.4.因特网的组成 2.三种交换方式 2.1电路交换 2.2分组交换 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网…