通讯基础 -- 嵌入式Linux ZeroMQ 使用笔记

嵌入式Linux ZeroMQ 使用笔记

ZeroMQ 简介

ZeroMQ(ØMQ)是一种高性能的异步消息库,广泛应用于分布式系统中的任务间通信。它提供了简单、灵活的通信抽象,适用于多种场景,如点对点通信、一对多通信等。


ZeroMQ 的主要作用

  1. 分布式通信框架:支持多种通信模式,简化分布式系统的实现。
  2. 抽象化的网络通信:屏蔽底层通信细节,开发者可以专注于消息逻辑。
  3. 高性能:基于异步I/O和内存优化,提供低延迟和高吞吐。
  4. 跨语言支持:支持多种语言绑定,如C、C++、Python等。
  5. 可扩展性:适用于P2P和发布-订阅模式的复杂分布式系统。

ZeroMQ 的使用

通信模式

1. 请求-应答模式(Request-Reply)

请求-应答是最基本的同步模式,通常用于客户端与服务器的通信。

示例:Python 实现

服务端:

import zmq

context = zmq.Context()
socket = context.socket(zmq.REP)  # 响应模式
socket.bind("tcp://*:5555")

while True:
    message = socket.recv_string()
    print("Received request:", message)
    socket.send_string("World")

客户端:

import zmq

context = zmq.Context()
socket = context.socket(zmq.REQ)  # 请求模式
socket.connect("tcp://localhost:5555")

socket.send_string("Hello")
reply = socket.recv_string()
print("Received reply:", reply)
2. 发布-订阅模式(Publish-Subscribe)

发布-订阅适用于广播消息场景,发布者根据主题发送,订阅者接收特定主题的消息。

示例:Python 实现

发布者:

import zmq

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")

socket.send_string("topic1 Hello World")

订阅者:

import zmq

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
socket.setsockopt_string(zmq.SUBSCRIBE, "topic1")  # 订阅主题

message = socket.recv_string()
print("Received:", message)

发布-订阅消息处理时序:

  1. 发布者创建 PUB 套接字,绑定到地址并发送消息。
  2. 订阅者创建 SUB 套接字,连接到发布者的地址,设置订阅的主题。
  3. 发布者将消息广播给所有订阅者。
  4. 订阅者接收符合主题的消息并处理。
3. 推-拉模式(Push-Pull)

推-拉模式用于任务分发和并行处理。

示例:Python 实现

推送者:

import zmq

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.bind("tcp://*:5557")

socket.send_string("Task 1")

拉取者:

import zmq

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.connect("tcp://localhost:5557")

task = socket.recv_string()
print("Received task:", task)

嵌入式C语言实现示例

1. 请求-应答模式

服务端:

#include <zmq.h>
#include <stdio.h>
#include <string.h>

int main() {
    void *context = zmq_ctx_new();
    void *responder = zmq_socket(context, ZMQ_REP);
    zmq_bind(responder, "tcp://*:5555");

    char buffer[10];
    while (1) {
        zmq_recv(responder, buffer, 10, 0);
        printf("Received: %s\n", buffer);
        zmq_send(responder, "World", 5, 0);
    }

    zmq_close(responder);
    zmq_ctx_destroy(context);
    return 0;
}

客户端:

#include <zmq.h>
#include <stdio.h>
#include <string.h>

int main() {
    void *context = zmq_ctx_new();
    void *requester = zmq_socket(context, ZMQ_REQ);
    zmq_connect(requester, "tcp://localhost:5555");

    char buffer[10];
    zmq_send(requester, "Hello", 5, 0);
    zmq_recv(requester, buffer, 10, 0);
    printf("Received: %s\n", buffer);

    zmq_close(requester);
    zmq_ctx_destroy(context);
    return 0;
}
2. 发布-订阅模式

发布者:

#include <zmq.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    void *context = zmq_ctx_new();
    void *publisher = zmq_socket(context, ZMQ_PUB);
    zmq_bind(publisher, "tcp://*:5556");

    while (1) {
        zmq_send(publisher, "topic1 Hello World", 19, 0);
        sleep(1);
    }

    zmq_close(publisher);
    zmq_ctx_destroy(context);
    return 0;
}

订阅者:

#include <zmq.h>
#include <stdio.h>
#include <string.h>

int main() {
    void *context = zmq_ctx_new();
    void *subscriber = zmq_socket(context, ZMQ_SUB);
    zmq_connect(subscriber, "tcp://localhost:5556");
    zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "topic1", strlen("topic1"));

    char buffer[256];
    while (1) {
        zmq_recv(subscriber, buffer, 256, 0);
        printf("Received: %s\n", buffer);
    }

    zmq_close(subscriber);
    zmq_ctx_destroy(context);
    return 0;
}

ZeroMQ 的移植步骤

1. 获取 ZeroMQ 源码

ZeroMQ 是一个开源项目,源码可以从 官方 GitHub 仓库 获取。

git clone https://github.com/zeromq/libzmq.git
cd libzmq

2. 配置目标平台环境

工具链

确保目标平台的交叉编译工具链已经安装,并可用。例如:

  • ARM 平台:arm-none-eabi-gccaarch64-linux-gnu-gcc
  • MIPS 平台:mipsel-linux-gcc
依赖项

ZeroMQ 依赖以下库:

  • libpthread:线程支持
  • libsodium(可选):支持 Curve 加密
  • libstdc++:C++ 标准库(如果启用了 C++ 支持)

在目标平台上需要确保这些依赖库可用,或者也需要移植这些依赖库。


3. 构建系统支持

ZeroMQ 使用 CMake 进行构建。

使用 CMake

适合现代项目和跨平台支持。

  1. 确保目标平台的 CMake 可用。
  2. 配置交叉编译工具链文件。例如,创建一个 toolchain.cmake 文件:
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    
    set(CMAKE_C_COMPILER /path/to/arm-linux-gnueabihf-gcc)
    set(CMAKE_CXX_COMPILER /path/to/arm-linux-gnueabihf-g++)
    set(CMAKE_FIND_ROOT_PATH /path/to/target/sysroot)
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    
  3. 执行 CMake 构建:
    mkdir build && cd build
    cmake .. -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DENABLE_CURVE=OFF -DENABLE_DRAFTS=OFF
    make
    

4. 移植依赖项

libsodium

ZeroMQ 可以启用 Curve 加密功能,这需要 libsodium 支持。移植步骤如下:

  1. 获取源码:
    git clone https://github.com/jedisct1/libsodium.git
    cd libsodium
    
  2. 配置并构建:
    ./configure --host=arm-linux-gnueabihf --prefix=/output/path
    make
    make install
    
libpthread
  • 大部分嵌入式 Linux 系统默认支持 libpthread
  • 确保目标平台的 C 库(如 glibc、musl)已包含线程支持。

5. 测试 ZeroMQ

移植完成后,编译一个简单的测试程序,验证 ZeroMQ 的功能。

示例:请求-应答模式

服务端代码:

#include <zmq.h>
#include <string.h>
#include <stdio.h>

int main() {
    void *context = zmq_ctx_new();
    void *responder = zmq_socket(context, ZMQ_REP);
    zmq_bind(responder, "tcp://*:5555");

    char buffer[10];
    while (1) {
        zmq_recv(responder, buffer, 10, 0);
        printf("Received: %s\n", buffer);
        zmq_send(responder, "World", 5, 0);
    }

    zmq_close(responder);
    zmq_ctx_destroy(context);
    return 0;
}

客户端代码:

#include <zmq.h>
#include <string.h>
#include <stdio.h>

int main() {
    void *context = zmq_ctx_new();
    void *requester = zmq_socket(context, ZMQ_REQ);
    zmq_connect(requester, "tcp://<target-ip>:5555");

    zmq_send(requester, "Hello", 5, 0);
    char buffer[10];
    zmq_recv(requester, buffer, 10, 0);
    printf("Received: %s\n", buffer);

    zmq_close(requester);
    zmq_ctx_destroy(context);
    return 0;
}

编译和运行:

arm-linux-gnueabihf-gcc server.c -o server -lzmq
arm-linux-gnueabihf-gcc client.c -o client -lzmq

总结

ZeroMQ 是一个灵活、高效的消息库,适用于嵌入式和分布式系统。在移植过程中,需要根据目标平台配置交叉编译环境,并解决依赖库的问题。通过本文档,您可以顺利完成 ZeroMQ 的移植工作并验证其功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值