【网络编程】ZeroMQ的网络通信

2024-02-18 11:52

本文主要是介绍【网络编程】ZeroMQ的网络通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1、概述
  • 2、通信效果
    • 2.1、Request-Reply(请求-响应模式)
    • 2.2、Publish-Subscribe(订阅-发布模式)
  • 3、方式选择
    • 3.1、准备用 Visual Studio-C++ 方式
      • 3.1.1、找到 Builds 文件夹
      • 3.1.2、查看 deprecated-msvc 下的 libzmq.sln 文件
      • 3.1.3、使用 Visual Studio 打开 libzmq.sln 解决方案
      • 3.1.4、修改 libzmq.import.props 文件
      • 3.1.5、编译生成
    • 3.2、准备用 PyCharm-Python 方式
      • 3.2.1、安装
        • 3.2.1.1、命令安装
        • 3.2.1.2、IDE安装
      • 3.2.2、查看是否安装成功
  • 4、Request-Reply(请求响应模式)
    • 4.1、Request-Reply模式概述
    • 4.2、Client 源代码
    • 4.3、Server 源代码
  • 5、Publish/Subscribe(订阅-发布模式)
    • 5.1、Pub-Subs模式概述
    • 5.2、发布者 源代码
    • 5.3、订阅者 源代码

1、概述

在前一篇文章中提到了 ØMQ (ZeroMQ) ,是一个基于消息队列的多线程网络库,它封装了网络通信、消息队列、线程调度等功能,向上层提供简洁的API,应用程序通过加载库文件,调用API函数来实现高性能网络通信。

本篇文章重点讲述下,在客户端上如何使用 ZeroMQ 与 服务端的 ZeroMQ 进行通信,主要讲述两种常用模式:
1.Request-Reply(请求响应模式)
2.Publish-Subscribe(订阅-发布模式)

相关文章:

  • 【Qt 学习之路】在 Qt 使用 ZeroMQ:https://shazhenyu.blog.csdn.net/article/details/136051050?spm=1001.2014.3001.5502

2、通信效果

2.1、Request-Reply(请求-响应模式)

Client:
在这里插入图片描述
Server:
在这里插入图片描述

2.2、Publish-Subscribe(订阅-发布模式)

发布者:
在这里插入图片描述
订阅者:
在这里插入图片描述
在这里插入图片描述

3、方式选择

3.1、准备用 Visual Studio-C++ 方式

3.1.1、找到 Builds 文件夹

在 ZeroMQ 的 builds 文件夹下,有很多种编译方法,为了方便演示,本文选择msvc进行演示。
在这里插入图片描述

3.1.2、查看 deprecated-msvc 下的 libzmq.sln 文件

在这里插入图片描述

3.1.3、使用 Visual Studio 打开 libzmq.sln 解决方案

在这里插入图片描述

3.1.4、修改 libzmq.import.props 文件

用 Notepad++ 打开 libzmq.import.props 文件,修改 5处 路径,全部改成…\bin【注意:去掉“…\libzmq\”】

  • 原:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><PropertyGroup Label="Globals"><_PropertySheetDisplayName>ZMQ Import Settings</_PropertySheetDisplayName></PropertyGroup><!-- User Interface --><ItemGroup Label="BuildOptionsExtension"><PropertyPageSchema Include="$(MSBuildThisFileDirectory)libzmq.import.xml" /></ItemGroup><!-- Configuration --><ItemDefinitionGroup><ClCompile><PreprocessorDefinitions Condition="'$(Option-sodium)' == 'true'">ZMQ_USE_LIBSODIUM;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-openpgm)' == 'true'">ZMQ_HAVE_OPENPGM;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-gssapi)' == 'true'">HAVE_LIBGSSAPI_KRB5;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-draftapi)' == 'true'">ZMQ_BUILD_DRAFT_API;%(PreprocessorDefinitions)</PreprocessorDefinitions></ClCompile></ItemDefinitionGroup><!-- Linkage --><ItemDefinitionGroup><ClCompile><AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\..\libzmq\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories><PreprocessorDefinitions Condition="'$(Linkage-libzmq)' == 'static' Or '$(Linkage-libzmq)' == 'ltcg'">ZMQ_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions></ClCompile><Link><AdditionalDependencies Condition="'$(Linkage-libzmq)' != ''">libzmq.lib;%(AdditionalDependencies)</AdditionalDependencies><AdditionalLibraryDirectories Condition="$(Configuration.IndexOf('Debug')) != -1">$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libzmq)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories><AdditionalLibraryDirectories Condition="$(Configuration.IndexOf('Release')) != -1">$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libzmq)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories></Link></ItemDefinitionGroup><!-- Copy --><Target Name="Linkage-libzmq-dynamic" AfterTargets="AfterBuild" Condition="'$(Linkage-libzmq)' == 'dynamic'"><Copy Condition="$(Configuration.IndexOf('Debug')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.dll"DestinationFiles="$(TargetDir)libzmq.dll"SkipUnchangedFiles="true" /><Copy Condition="$(Configuration.IndexOf('Debug')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.pdb"DestinationFiles="$(TargetDir)libzmq.pdb"SkipUnchangedFiles="true" /><Copy Condition="$(Configuration.IndexOf('Release')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Release\$(PlatformToolset)\dynamic\libzmq.dll"DestinationFiles="$(TargetDir)libzmq.dll"SkipUnchangedFiles="true" /></Target><!-- Messages --><Target Name="libzmq-info" BeforeTargets="AfterBuild" Condition="'$(Linkage-libzmq)' == 'dynamic'"><Message Text="Copying libzmq.dll -&gt; $(TargetDir)libzmq.dll" Importance="high"/><Message Text="Copying libzmq.pdb -&gt; $(TargetDir)libzmq.pdb" Importance="high" Condition="$(Configuration.IndexOf('Debug')) != -1" /></Target></Project>
  • 改:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><PropertyGroup Label="Globals"><_PropertySheetDisplayName>ZMQ Import Settings</_PropertySheetDisplayName></PropertyGroup><!-- User Interface --><ItemGroup Label="BuildOptionsExtension"><PropertyPageSchema Include="$(MSBuildThisFileDirectory)libzmq.import.xml" /></ItemGroup><!-- Configuration --><ItemDefinitionGroup><ClCompile><PreprocessorDefinitions Condition="'$(Option-sodium)' == 'true'">ZMQ_USE_LIBSODIUM;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-openpgm)' == 'true'">ZMQ_HAVE_OPENPGM;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-gssapi)' == 'true'">HAVE_LIBGSSAPI_KRB5;%(PreprocessorDefinitions)</PreprocessorDefinitions><PreprocessorDefinitions Condition="'$(Option-draftapi)' == 'true'">ZMQ_BUILD_DRAFT_API;%(PreprocessorDefinitions)</PreprocessorDefinitions></ClCompile></ItemDefinitionGroup><!-- Linkage --><ItemDefinitionGroup><ClCompile><AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\..\libzmq\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories><PreprocessorDefinitions Condition="'$(Linkage-libzmq)' == 'static' Or '$(Linkage-libzmq)' == 'ltcg'">ZMQ_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions></ClCompile><Link><AdditionalDependencies Condition="'$(Linkage-libzmq)' != ''">libzmq.lib;%(AdditionalDependencies)</AdditionalDependencies><AdditionalLibraryDirectories Condition="$(Configuration.IndexOf('Debug')) != -1">$(ProjectDir)..\..\..\..\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libzmq)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories><AdditionalLibraryDirectories Condition="$(Configuration.IndexOf('Release')) != -1">$(ProjectDir)..\..\..\..\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libzmq)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories></Link></ItemDefinitionGroup><!-- Copy --><Target Name="Linkage-libzmq-dynamic" AfterTargets="AfterBuild" Condition="'$(Linkage-libzmq)' == 'dynamic'"><Copy Condition="$(Configuration.IndexOf('Debug')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.dll"DestinationFiles="$(TargetDir)libzmq.dll"SkipUnchangedFiles="true" /><Copy Condition="$(Configuration.IndexOf('Debug')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.pdb"DestinationFiles="$(TargetDir)libzmq.pdb"SkipUnchangedFiles="true" /><Copy Condition="$(Configuration.IndexOf('Release')) != -1"SourceFiles="$(ProjectDir)..\..\..\..\bin\$(PlatformName)\Release\$(PlatformToolset)\dynamic\libzmq.dll"DestinationFiles="$(TargetDir)libzmq.dll"SkipUnchangedFiles="true" /></Target><!-- Messages --><Target Name="libzmq-info" BeforeTargets="AfterBuild" Condition="'$(Linkage-libzmq)' == 'dynamic'"><Message Text="Copying libzmq.dll -&gt; $(TargetDir)libzmq.dll" Importance="high"/><Message Text="Copying libzmq.pdb -&gt; $(TargetDir)libzmq.pdb" Importance="high" Condition="$(Configuration.IndexOf('Debug')) != -1" /></Target></Project>

3.1.5、编译生成

按照官网的方式,这一步应该是成功了,但是目前是失败,还少文件,可能是包有问题
在这里插入图片描述

3.2、准备用 PyCharm-Python 方式

3.2.1、安装

3.2.1.1、命令安装
pip install pyzmq
3.2.1.2、IDE安装

安装图种方法安装 pyzmq25.1.2 版本
在这里插入图片描述

3.2.2、查看是否安装成功

直接打印 zmq 版本号 试试

import zmq
print(zmq.__version__)

在这里插入图片描述
由于 Python 相对快捷,本文后续以 Python 进行讲述

4、Request-Reply(请求响应模式)

4.1、Request-Reply模式概述

消息双向的,有来有往。
Client请求的消息,Server必须答复给Client。
Client在请求后,Server必须回响应,注意:Server不返回响应会报错。
Server和Client都可以是1:N的模型。通常把1认为是Server,N认为是Client。
更底层的端点地址是对上层隐藏的,每个请求都隐含回应地址,而应用则不关心它。
ZMQ 可以很好的支持路由功能(实现路由功能的组件叫做 Device),把 1:N 扩展为 N:M(只需要加入若干路由节点)。

4.2、Client 源代码

# client.pyimport zmqcontext = zmq.Context()#  Socket to talk to server
print("Connecting to 5555 server…")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")
socket.send(b"Hello, I'm Mr.Sha Client.")
#  Get the reply.
message = socket.recv()
print(f"Received reply [ {message} ]")

4.3、Server 源代码

# server.py
import time
import zmqcontext = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")while True:#  Wait for next request from clientmessage = socket.recv()print("Received request: %s" % message)#  Do some 'work'time.sleep(1)#  Send reply back to clientsocket.send(b"Hello, I'm server.")

5、Publish/Subscribe(订阅-发布模式)

5.1、Pub-Subs模式概述

消息单向,有去无回
一个发布端,多个订阅端;发布端只管产生数据,发布端发布一条消息,可被多个订阅端同时收到。
发布者不必关心订阅者的加入和离开,消息会以 1:N 的方式扩散到每个订阅者。
广播所有client,没有队列缓存,断开连接数据将永远丢失。
如果Publish端开始发布信息时,Subscribe端尚未连接进来,则这些信息会被直接丢弃。
PUB和SUB谁bind谁connect并无严格要求(虽本质并无区别),但仍建议PUB使用bind,SUB使用connect
使用SUB设置一个订阅时,必须使用zmq_setsockopt()对消息进行过滤

这里直接引用官方文档的例子,订阅者再稍作改装!

5.2、发布者 源代码

类似于一个天气更新服务器,向订阅者发送天气更新,内容包括邮政编码、温度、湿度等信息

# Publisher.py
import zmq
from random import randrangecontext = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")while True:zipcode = randrange(1, 100000)temperature = randrange(-80, 135)relhumidity = randrange(10, 60)socket.send_string("%i %i %i" % (zipcode, temperature, relhumidity))

5.3、订阅者 源代码

它监听发布者更新的数据流,过滤只接收与特定邮政编码相关的天气信息,默认接收接收10条数据

# Subscribe.py
import sys
import zmq#  Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)print("Collecting updates from weather server...")
socket.connect("tcp://localhost:5556")# Subscribe to zipcode, default is NYC, 10001
zip_filter = sys.argv[1] if len(sys.argv) > 1 else "10001"# Python 2 - ascii bytes to unicode str
if isinstance(zip_filter, bytes):zip_filter = zip_filter.decode('ascii')
socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter)# Process 5 updates
total_temp = 0
for update_nbr in range(5):string = socket.recv_string()zipcode, temperature, relhumidity = string.split()total_temp += int(temperature)print("zipcode, temperature, relhumidity:" + string)print("Average temperature for zipcode '%s' was %dF"% (zip_filter, total_temp / (update_nbr + 1))
)

这篇关于【网络编程】ZeroMQ的网络通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/721070

相关文章

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

16.Spring前世今生与Spring编程思想

1.1.课程目标 1、通过对本章内容的学习,可以掌握Spring的基本架构及各子模块之间的依赖关系。 2、 了解Spring的发展历史,启发思维。 3、 对 Spring形成一个整体的认识,为之后的深入学习做铺垫。 4、 通过对本章内容的学习,可以了解Spring版本升级的规律,从而应用到自己的系统升级版本命名。 5、Spring编程思想总结。 1.2.内容定位 Spring使用经验

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

Toolbar+DrawerLayout使用详情结合网络各大神

最近也想搞下toolbar+drawerlayout的使用。结合网络上各大神的杰作,我把大部分的内容效果都完成了遍。现在记录下各个功能效果的实现以及一些细节注意点。 这图弹出两个菜单内容都是仿QQ界面的选项。左边一个是drawerlayout的弹窗。右边是toolbar的popup弹窗。 开始实现步骤详情: 1.创建toolbar布局跟drawerlayout布局 <?xml vers

常用MQ消息中间件Kafka、ZeroMQ和RabbitMQ对比及RabbitMQ详解

1、概述   在现代的分布式系统和实时数据处理领域,消息中间件扮演着关键的角色,用于解决应用程序之间的通信和数据传递的挑战。在众多的消息中间件解决方案中,Kafka、ZeroMQ和RabbitMQ 是备受关注和广泛应用的代表性系统。它们各自具有独特的特点和优势,适用于不同的应用场景和需求。   Kafka 是一个高性能、可扩展的分布式消息队列系统,被设计用于处理大规模的数据流和实时数据传输。它

IPython小白教程:提升你的Python交互式编程技巧,通俗易懂!

IPython是一个增强的Python交互式shell,它提供了丰富的功能和便捷的交互方式,使得Python开发和数据分析工作更加高效。本文将详细介绍IPython的基本概念、使用方法、主要作用以及注意事项。 一、IPython简介 1. IPython的起源 IPython由Fernando Pérez于2001年创建,旨在提供一个更高效的Python交互式编程环境。 2. IPyt

从《深入设计模式》一书中学到的编程智慧

软件设计原则   优秀设计的特征   在开始学习实际的模式前,让我们来看看软件架构的设计过程,了解一下需要达成目标与需要尽量避免的陷阱。 代码复用 无论是开发何种软件产品,成本和时间都最重要的两个维度。较短的开发时间意味着可比竞争对手更早进入市场; 较低的开发成本意味着能够留出更多营销资金,因此能更广泛地覆盖潜在客户。 代码复用是减少开发成本时最常用的方式之一。其意图

LoRaWAN在嵌入式网络通信中的应用:打造高效远程监控系统(附代码示例)

引言 随着物联网(IoT)技术的发展,远程监控系统在各个领域的应用越来越广泛。LoRaWAN(Long Range Wide Area Network)作为一种低功耗广域网通信协议,因其长距离传输、低功耗和高可靠性等特点,成为实现远程监控的理想选择。本文将详细介绍LoRaWAN的基本原理、应用场景,并通过一个具体的项目展示如何使用LoRaWAN实现远程监控系统。希望通过图文并茂的讲解,帮助读