Nanomsg:高性能的消息传递库在嵌入式开发中跨进程、跨设备、分布式系统的应用

在嵌入式开发中,可靠的消息传递和通信机制是至关重要的。随着嵌入式系统变得越来越复杂,高效的通信协议和库变得尤为重要。Nanomsg 是一个高性能的消息传递库,它为开发者提供了简单而强大的工具来实现分布式系统中的通信。在这篇博客中,我们将探讨 Nanomsg 在嵌入式开发中的应用。


🧑 博主简介:现任阿里巴巴嵌入式技术专家,15年工作经验,深耕嵌入式+人工智能领域,精通嵌入式领域开发、技术管理、简历招聘面试。CSDN优质创作者,提供产品测评、学习辅导、简历面试辅导、毕设辅导、项目开发、C/C++/Java/Python/Linux/AI等方面的服务,如有需要请站内私信或者联系任意文章底部的的VX名片(ID:gylzbk

💬 博主粉丝群介绍:① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。③ 群内也有职场精英,大厂大佬,可交流技术、面试、找工作的经验。④ 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬。⑤ 进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

在这里插入图片描述

在这里插入图片描述

1. 什么是Nanomsg?

Nanomsg 是一个轻量级的高性能消息传递库,旨在提供简单易用的 API 来实现不同进程和设备之间的通信。它是 ZeroMQ 的后续版本,继承了 ZeroMQ 的许多优点,同时解决了一些设计上的不足。Nanomsg 支持多种消息传递模式,包括请求-响应、发布-订阅、管道、总线等。

2. Nanomsg 的特点

  1. 轻量级和高性能:Nanomsg 设计紧凑,适合嵌入式系统的资源受限环境。
  2. 多种通信模式:支持多种消息传递模式,满足不同应用场景的需求。
  3. 跨平台:支持多种操作系统,包括 Linux、Windows 和嵌入式操作系统。
  4. 简单易用的 API:提供统一的 API 接口,简化了开发过程。

3. Nanomsg 的安装

在 Linux 系统上,可以通过包管理器安装 Nanomsg:

sudo apt-get install libnanomsg-dev

或者从源码编译安装:

git clone https://github.com/nanomsg/nanomsg.git
cd nanomsg
mkdir build
cd build
cmake ..
make
sudo make install

4. Nanomsg 在嵌入式开发中的应用场景及示例

4.1 设备间通信

在嵌入式系统中,不同设备之间的通信是常见需求。Nanomsg 提供了多种通信模式,可以满足设备间的各种通信需求。下面是一个简单的示例,展示了如何使用 Nanomsg 实现设备间的请求-响应通信。

服务端代码(server.c):

#include <nanomsg/nn.h>
#include <nanomsg/reqrep.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define URL "tcp://192.168.1.100:5555"

int main() {
    int sock = nn_socket(AF_SP, NN_REP);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_bind(sock, URL) < 0) {
        perror("nn_bind");
        exit(1);
    }

    char *buf = NULL;
    while (1) {
        int bytes = nn_recv(sock, &buf, NN_MSG, 0);
        if (bytes < 0) {
            perror("nn_recv");
            exit(1);
        }
        printf("Received: %s\n", buf);
        nn_freemsg(buf);

        const char *response = "World";
        bytes = nn_send(sock, response, strlen(response) + 1, 0);
        if (bytes < 0) {
            perror("nn_send");
            exit(1);
        }
    }

    nn_close(sock);
    return 0;
}

客户端代码(client.c):

#include <nanomsg/nn.h>
#include <nanomsg/reqrep.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define URL "tcp://192.168.1.100:5555"

int main() {
    int sock = nn_socket(AF_SP, NN_REQ);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_connect(sock, URL) < 0) {
        perror("nn_connect");
        exit(1);
    }

    const char *msg = "Hello";
    int bytes = nn_send(sock, msg, strlen(msg) + 1, 0);
    if (bytes < 0) {
        perror("nn_send");
        exit(1);
    }

    char *buf = NULL;
    bytes = nn_recv(sock, &buf, NN_MSG, 0);
    if (bytes < 0) {
        perror("nn_recv");
        exit(1);
    }

    printf("Received: %s\n", buf);
    nn_freemsg(buf);

    nn_close(sock);
    return 0;
}

编译和运行

将上述代码保存为 server.c 和 client.c,然后分别编译:

gcc -o server server.c -lnanomsg
gcc -o client client.c -lnanomsg

首先在服务端设备(192.168.1.100)上运行服务端:

./server

然后在客户端设备(192.168.1.101)上运行客户端:

./client

结果

在客户端设备上,你应该会看到输出 “Received: World”,而在服务端设备上,你应该会看到输出 “Received: Hello”。

注意事项

防火墙设置:确保两台设备之间的网络连接没有被防火墙阻挡。如果有必要,可以临时关闭防火墙或添加例外规则。
网络连接:确保两台设备在同一网络中,或者能够互相访问。如果在不同的网络中,需要配置路由或使用 VPN。
IP 地址:确保使用的 IP 地址是设备的实际网络 IP 地址,而不是本地回环地址(127.0.0.1)。

通过这些设置,我们可以实现真正的跨设备通信,展示 Nanomsg 在嵌入式开发中的应用。

4.2 进程间通信

在嵌入式系统中,进程间通信(IPC)是一个常见的需求。Nanomsg 提供了高效的 IPC 机制,可以用来在同一设备的不同进程之间传递数据。下面是一个简单的示例,展示了如何使用 Nanomsg 实现进程间的请求-响应通信。

服务端代码(ipc_server.c):

#include <nanomsg/nn.h>
#include <nanomsg/reqrep.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define URL "ipc:///tmp/reqrep.ipc"

int main() {
    int sock = nn_socket(AF_SP, NN_REP);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_bind(sock, URL) < 0) {
        perror("nn_bind");
        exit(1);
    }

    char *buf = NULL;
    while (1) {
        int bytes = nn_recv(sock, &buf, NN_MSG, 0);
        if (bytes < 0) {
            perror("nn_recv");
            exit(1);
        }
        printf("Received: %s\n", buf);
        nn_freemsg(buf);

        const char *response = "World";
        bytes = nn_send(sock, response, strlen(response) + 1, 0);
        if (bytes < 0) {
            perror("nn_send");
            exit(1);
        }
    }

    nn_close(sock);
    return 0;
}

客户端代码(ipc_client.c):

#include <nanomsg/nn.h>
#include <nanomsg/reqrep.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define URL "ipc:///tmp/reqrep.ipc"

int main() {
    int sock = nn_socket(AF_SP, NN_REQ);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_connect(sock, URL) < 0) {
        perror("nn_connect");
        exit(1);
    }

    const char *msg = "Hello";
    int bytes = nn_send(sock, msg, strlen(msg) + 1, 0);
    if (bytes < 0) {
        perror("nn_send");
        exit(1);
    }

    char *buf = NULL;
    bytes = nn_recv(sock, &buf, NN_MSG, 0);
    if (bytes < 0) {
        perror("nn_recv");
        exit(1);
    }

    printf("Received: %s\n", buf);
    nn_freemsg(buf);

    nn_close(sock);
    return 0;
}

编译和运行

将上述代码保存为 server.c 和 client.c,然后分别编译:

gcc -o server server.c -lnanomsg
gcc -o client client.c -lnanomsg

首先运行服务端:

./server

然后在另一个终端窗口运行客户端:

./client

结果

你应该会看到服务端输出 “Received: Hello” 并且客户端输出 “Received: World”。

4.3 分布式系统

在分布式嵌入式系统中,多个设备需要协同工作。Nanomsg 的发布-订阅模式非常适合用于传感器网络、实时数据广播等场景。下面是一个分布式系统的示例,展示了如何使用 Nanomsg 实现发布-订阅模式的通信。

假设我们有三台设备:

  • 发布者设备:192.168.1.100
  • 订阅者设备1:192.168.1.101
  • 订阅者设备2:192.168.1.102

发布者代码(publisher.c):

#include <nanomsg/nn.h>
#include <nanomsg/pubsub.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define URL "tcp://192.168.1.100:5555"

int main() {
    int sock = nn_socket(AF_SP, NN_PUB);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_bind(sock, URL) < 0) {
        perror("nn_bind");
        exit(1);
    }

    while (1) {
        const char *msg = "Hello, Subscribers!";
        int bytes = nn_send(sock, msg, strlen(msg) + 1, 0);
        if (bytes < 0) {
            perror("nn_send");
            exit(1);
        }
        printf("Sent: %s\n", msg);
        sleep(1); // 每秒发送一次消息
    }

    nn_close(sock);
    return 0;
}

订阅者代码(subscriber.c):

#include <nanomsg/nn.h>
#include <nanomsg/pubsub.h>
#include <stdio.h>
#include <stdlib.h>

#define URL "tcp://192.168.1.100:5555"

int main() {
    int sock = nn_socket(AF_SP, NN_SUB);
    if (sock < 0) {
        perror("nn_socket");
        exit(1);
    }

    if (nn_connect(sock, URL) < 0) {
        perror("nn_connect");
        exit(1);
    }

    if (nn_setsockopt(sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0) < 0) {
        perror("nn_setsockopt");
        exit(1);
    }

    char *buf = NULL;
    while (1) {
        int bytes = nn_recv(sock, &buf, NN_MSG, 0);
        if (bytes < 0) {
            perror("nn_recv");
            exit(1);
        }
        printf("Received: %s\n", buf);
        nn_freemsg(buf);
    }

    nn_close(sock);
    return 0;
}

编译和运行

将上述代码保存为 publisher.csubscriber.c,然后分别编译:

gcc -o publisher publisher.c -lnanomsg
gcc -o subscriber subscriber.c -lnanomsg

首先在发布者设备(192.168.1.100)上运行发布者:

./publisher

然后在两个订阅者设备(192.168.1.101 和 192.168.1.102)上分别运行订阅者:

./subscriber

结果

在发布者设备上,你应该会看到每秒发送一次消息 “Sent: Hello, Subscribers!”。

在两个订阅者设备上,你应该会看到每秒接收到一次消息 “Received: Hello, Subscribers!”。

注意事项

  1. 防火墙设置:确保防火墙没有阻挡两台设备之间的网络连接。如果有必要,可以临时关闭防火墙或添加例外规则。
  2. 网络连接:确保设备在同一网络中,或者能够互相访问。如果在不同的网络中,需要配置路由或使用 VPN。
  3. IP 地址:确保使用的是设备的实际网络 IP 地址,而不是本地回环地址(127.0.0.1)。

通过这个分布式系统的示例,我们展示了 Nanomsg 在分布式环境中的应用。发布-订阅模式非常适合用于传感器网络、实时数据广播等场景。

5. 结论

Nanomsg 是一个强大且灵活的消息传递库,非常适合嵌入式开发中的多种应用场景。它的轻量级和高性能特性使其成为嵌入式系统中实现设备间、进程间和分布式通信的理想选择。尽管存在一些局限,但通过合理的设计和使用,Nanomsg 可以极大地简化嵌入式系统的通信开发。

希望这篇博客能帮助你更好地理解和应用 Nanomsg 在嵌入式开发中的潜力。如果你有任何问题或需要进一步的帮助,请随时留言讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I'mAlex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值