Linux 环境下 NNG 通讯库:在嵌入式设备上应用
NNG(Nanomsg Next Generation)是一款轻量级的跨平台消息传递库,专为分布式系统设计。相比传统Socket和ZeroMQ,NNG具有无依赖、体积小(约500KB)、接口简洁等优势,支持多种通信模式(如REQ/REP、PUB/SUB等)。特别适合Linux嵌入式设备和实时系统开发,通过异步I/O处理高并发连接,内置可靠性机制。示例展示了PUB/SUB模式实现温度数据推送,体现其
在嵌入式设备开发中,进程间通信(IPC)和网络通信是核心环节。传统的 Socket 编程需要处理复杂的连接管理、协议解析和错误处理,而第三方库如 ZeroMQ 虽简化了流程,却存在依赖重、接口复杂等问题。NNG(Nanomsg Next Generation) 作为 Nanomsg 的继任者,以 “轻量、灵活、无依赖” 为核心优势,
一、NNG 是什么?
NNG 是一款跨平台的消息传递库,专为解决分布式系统中 “进程如何高效交换数据” 的问题而设计。它继承了 Nanomsg 的核心思想,同时优化了 API 设计、性能和可扩展性,尤其适合 Linux 环境下的嵌入式设备、微服务架构和实时数据传输场景。
与传统方案的对比优势
- 对比原生 Socket:无需手动处理 TCP 粘包、UDP 丢包等底层细节,NNG 封装了消息边界处理、连接复用等逻辑,开发者可直接基于 “消息” 而非 “字节流” 编程。
- 对比 ZeroMQ:NNG 体积更小(静态库约 500KB)、无外部依赖(不依赖 libzmq 等库),且 API 更简洁(如统一的nng_send/nng_recv接口),编译部署更轻便。
- 对比 gRPC:不依赖 HTTP/2 或 Protocol Buffers,适合对性能敏感、需自定义协议的场景,且支持更多通信模式(如 PUB/SUB、BUS)。
二、NNG 的核心特性
NNG 的灵活性源于其支持的多通信模式,开发者可根据业务场景选择合适的模式,无需重复设计通信逻辑。
1. 核心技术特性
- 轻量级:无守护进程,库文件体积小,内存占用低,适合嵌入式 Linux 系统(如 ARM 架构的物联网设备)。
- 异步支持:通过nng_aio接口实现异步 I/O,可在单线程内处理 thousands 级并发连接,避免多线程上下文切换开销。
- 跨平台兼容:完美支持 Linux(x86/ARM)、Windows、macOS,代码可无缝移植,尤其适合多端协同的分布式系统。
- 内置可靠性:在 UDP 基础上实现了可靠消息传递(如Survey模式的确认机制),平衡性能与可靠性。
2. 常用通信模式解析
NNG 的通信模式基于 “套接字类型” 设计,每种模式对应特定的消息交互逻辑:
|
模式 |
适用场景 |
特点 |
|
REQ/REP |
客户端 - 服务器问答(如 API 调用) |
严格请求 - 响应配对,确保消息有序处理 |
|
PUB/SUB |
消息广播(如实时日志、行情推送) |
发布者单向发送,订阅者按需接收,支持主题过滤 |
|
PAIR |
点对点双向通信(如进程间协同) |
全双工通信,适合两个节点长期绑定 |
|
BUS |
多节点对等通信(如分布式集群) |
消息可被所有节点接收,支持多跳转发 |
|
PUSH/PULL |
任务分发(如分布式计算) |
推送端分发任务,拉取端负载均衡接收 |
三、Linux 环境下 NNG 实战:从安装到通信
1. 环境准备与安装
NNG 在 Linux 下的安装支持源码编译和包管理器两种方式,以 Ubuntu 20.04 为例:
源码编译(推荐,支持最新版本)
# 克隆仓库
git clone https://github.com/nanomsg/nng.git
cd nng
# 编译(默认生成动态库和静态库)
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j4
sudo make install # 安装到/usr/local/include和/usr/local/lib
包管理器安装
sudo apt update
sudo apt install libnng-dev # 包含头文件和共享库
2. 实战案例:PUB/SUB 模式实现实时消息推送
PUB/SUB(发布 - 订阅)模式适合 “一对多” 的消息分发场景(如实时监控系统中,服务器向多个客户端推送设备状态)。下面实现一个简单的数据推送系统:
发布端(pub.c):
#include <nng/nng.h>
#include <nng/protocol/pubsub0/pub.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
nng_socket pub_sock;
int ret;
// 创建PUB类型套接字
if ((ret = nng_pub0_open(&pub_sock)) != 0) {
fprintf(stderr, "创建套接字失败:%s\n", nng_strerror(ret));
return 1;
}
// 绑定到TCP端口(支持IPC:"ipc:///tmp/temp_pub.ipc")
if ((ret = nng_listen(pub_sock, "tcp://0.0.0.0:9000", NULL, 0)) != 0) {
fprintf(stderr, "绑定端口失败:%s\n", nng_strerror(ret));
nng_close(pub_sock);
return 1;
}
// 模拟温度数据推送
float temp = 22.0f;
while (1) {
char msg[32];
sprintf(msg, "temp:%.1f°C", temp + (rand() % 10 - 5) * 0.1); // 随机波动
ret = nng_send(pub_sock, msg, strlen(msg), 0);
if (ret != 0) {
fprintf(stderr, "发送失败:%s\n", nng_strerror(ret));
} else {
printf("推送:%s\n", msg);
}
temp += 0.1;
sleep(2);
}
nng_close(pub_sock);
return 0;
}
订阅端(sub.c):
#include <nng/nng.h>
#include <nng/protocol/pubsub0/sub.h>
#include <stdio.h>
#include <string.h>
int main()
{
nng_socket sub_sock;
int ret;
// 创建SUB类型套接字
if ((ret = nng_sub0_open(&sub_sock)) != 0) {
fprintf(stderr, "创建套接字失败:%s\n", nng_strerror(ret));
return 1;
}
// 订阅所有消息(若需过滤,可设置前缀,如nng_setopt(sub_sock, NNG_OPT_SUB_SUBSCRIBE, "temp:", 5))
nng_setopt(sub_sock, NNG_OPT_SUB_SUBSCRIBE, "", 0);
// 连接发布端
if ((ret = nng_dial(sub_sock, "tcp://127.0.0.1:9000", NULL, 0)) != 0) {
fprintf(stderr, "连接失败:%s\n", nng_strerror(ret));
nng_close(sub_sock);
return 1;
}
// 循环接收消息
while (1) {
char *msg;
size_t len;
ret = nng_recv(sub_sock, &msg, &len, NNG_FLAG_ALLOC); // 自动分配内存
if (ret != 0) {
fprintf(stderr, "接收失败:%s\n", nng_strerror(ret));
} else {
printf("收到:%.*s\n", (int)len, msg);
nng_free(msg, len); // 释放内存
}
}
nng_close(sub_sock);
return 0;
}
编译与运行
# 编译发布端和订阅端(链接nng库)
gcc pub.c -o pub -lnng
gcc sub.c -o sub -lnng
# 启动发布端(后台运行)
./pub &
# 启动多个订阅端(验证多客户端接收)
./sub
./sub
四、总结:NNG 在 Linux 生态中的应用价值
NNG 以 “轻量、灵活、高效” 的特性,无论是嵌入式设备的进程间协同,还是分布式服务的实时数据交换,NNG 都能通过丰富的通信模式和简洁的 API 降低开发成本。
相比传统方案,NNG 的优势在于:无需关注底层协议细节,专注业务逻辑;无依赖特性简化部署流程,尤其适合资源受限的 Linux 系统;跨平台兼容性保障多端协同的一致性。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)