IPC - 508364/NetLeaf GitHub Wiki
IPC(Inter-Process Communication)模块提供进程间通讯功能,支持 Windows Named Pipe 和 Linux Unix Domain Socket。
| 平台 | 实现方式 | 状态 | 说明 |
|---|---|---|---|
| Windows | Named Pipe | ✅ 完全支持 | 使用 \\.\pipe\<name> 格式路径 |
| Linux | Unix Domain Socket | ✅ 完全支持 | 使用文件系统路径,如 /tmp/netleaf_ipc
|
| macOS | 不支持 | ❌ 无实现 | 该模块在 macOS 上不可用 |
IPC 模块在 macOS 上 不提供任何功能:
- 所有 API 调用将返回错误码
-1 -
nl_ipc_is_available()返回0(不可用) - 模块初始化函数
nl_ipc_init()将返回错误 - 建议在使用前通过
nl_ipc_is_available()检查平台支持
// 检查IPC模块是否在当前平台可用
int nl_ipc_is_available(void);
// 初始化IPC模块
int nl_ipc_init(void);
// 关闭IPC模块
void nl_ipc_shutdown(void);// 创建IPC服务器
// path: Windows 使用 "\\\\.\\pipe\\<name>",Linux 使用文件路径如 "/tmp/netleaf_ipc"
nl_ipc_server_t* nl_ipc_server_create(const char* path);
// 启动IPC服务器(非阻塞)
int nl_ipc_server_start(nl_ipc_server_t* server);
// 停止IPC服务器
void nl_ipc_server_stop(nl_ipc_server_t* server);
// 销毁IPC服务器
void nl_ipc_server_destroy(nl_ipc_server_t* server);
// 设置数据回调
void nl_ipc_server_set_data_callback(nl_ipc_server_t* server,
void (*callback)(nl_ipc_client_t* client, const char* data, size_t len, void* user_data),
void* user_data);
// 设置客户端连接回调
void nl_ipc_server_set_connect_callback(nl_ipc_server_t* server,
void (*callback)(nl_ipc_client_t* client, void* user_data),
void* user_data);
// 设置客户端断开回调
void nl_ipc_server_set_disconnect_callback(nl_ipc_server_t* server,
void (*callback)(nl_ipc_client_t* client, void* user_data),
void* user_data);
// 向指定客户端发送数据
int nl_ipc_server_send_to(nl_ipc_server_t* server, nl_ipc_client_t* client,
const char* data, size_t len);
// 向所有客户端广播数据
int nl_ipc_server_broadcast(nl_ipc_server_t* server, const char* data, size_t len);
// 获取连接的客户端数量
int nl_ipc_server_get_client_count(nl_ipc_server_t* server);// 创建IPC客户端
nl_ipc_client_t* nl_ipc_client_create(const char* path);
// 连接到IPC服务器(阻塞调用,超时时间为5秒)
int nl_ipc_client_connect(nl_ipc_client_t* client);
// 带超时的连接(单位:毫秒)
int nl_ipc_client_connect_with_timeout(nl_ipc_client_t* client, int timeout_ms);
// 断开连接
void nl_ipc_client_disconnect(nl_ipc_client_t* client);
// 销毁IPC客户端
void nl_ipc_client_destroy(nl_ipc_client_t* client);
// 发送数据(阻塞)
int nl_ipc_client_send(nl_ipc_client_t* client, const char* data, size_t len);
// 设置数据回调
void nl_ipc_client_set_data_callback(nl_ipc_client_t* client,
void (*callback)(const char* data, size_t len, void* user_data),
void* user_data);
// 设置连接状态回调
void nl_ipc_client_set_status_callback(nl_ipc_client_t* client,
void (*callback)(int connected, void* user_data),
void* user_data);
// 检查连接状态
int nl_ipc_client_is_connected(nl_ipc_client_t* client);#include "netleaf_ipc.h"
#include <stdio.h>
void on_client_connect(nl_ipc_client_t* client, void* user_data) {
printf("Client connected\n");
}
void on_client_disconnect(nl_ipc_client_t* client, void* user_data) {
printf("Client disconnected\n");
}
void on_data_received(nl_ipc_client_t* client, const char* data, size_t len, void* user_data) {
nl_ipc_server_t* server = (nl_ipc_server_t*)user_data;
printf("Received: %.*s\n", (int)len, data);
// 回显数据给客户端
nl_ipc_server_send_to(server, client, data, len);
// 广播给所有客户端
nl_ipc_server_broadcast(server, data, len);
}
int main() {
// 检查平台支持
if (!nl_ipc_is_available()) {
printf("IPC module is not available on this platform\n");
return 1;
}
// 初始化模块
if (nl_ipc_init() != 0) {
printf("Failed to initialize IPC module\n");
return 1;
}
#ifdef _WIN32
const char* pipe_path = "\\\\.\\pipe\\netleaf_example";
#else
const char* pipe_path = "/tmp/netleaf_example";
#endif
// 创建服务器
nl_ipc_server_t* server = nl_ipc_server_create(pipe_path);
if (!server) {
printf("Failed to create IPC server\n");
nl_ipc_shutdown();
return 1;
}
// 设置回调
nl_ipc_server_set_connect_callback(server, on_client_connect, NULL);
nl_ipc_server_set_disconnect_callback(server, on_client_disconnect, NULL);
nl_ipc_server_set_data_callback(server, on_data_received, server);
// 启动服务器
if (nl_ipc_server_start(server) != 0) {
printf("Failed to start IPC server\n");
nl_ipc_server_destroy(server);
nl_ipc_shutdown();
return 1;
}
printf("IPC server started on: %s\n", pipe_path);
// 保持运行
while (1) {
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
// 清理
nl_ipc_server_stop(server);
nl_ipc_server_destroy(server);
nl_ipc_shutdown();
return 0;
}#include "netleaf_ipc.h"
#include <stdio.h>
#include <string.h>
void on_data_received(const char* data, size_t len, void* user_data) {
printf("Server response: %.*s\n", (int)len, data);
}
void on_status_changed(int connected, void* user_data) {
printf("Connection status: %s\n", connected ? "connected" : "disconnected");
}
int main() {
// 检查平台支持
if (!nl_ipc_is_available()) {
printf("IPC module is not available on this platform\n");
return 1;
}
// 初始化模块
if (nl_ipc_init() != 0) {
printf("Failed to initialize IPC module\n");
return 1;
}
#ifdef _WIN32
const char* pipe_path = "\\\\.\\pipe\\netleaf_example";
#else
const char* pipe_path = "/tmp/netleaf_example";
#endif
// 创建客户端
nl_ipc_client_t* client = nl_ipc_client_create(pipe_path);
if (!client) {
printf("Failed to create IPC client\n");
nl_ipc_shutdown();
return 1;
}
// 设置回调
nl_ipc_client_set_data_callback(client, on_data_received, NULL);
nl_ipc_client_set_status_callback(client, on_status_changed, NULL);
// 连接到服务器(带超时)
printf("Connecting to %s...\n", pipe_path);
int result = nl_ipc_client_connect_with_timeout(client, 3000);
if (result != 0) {
printf("Failed to connect to server\n");
nl_ipc_client_destroy(client);
nl_ipc_shutdown();
return 1;
}
printf("Connected successfully\n");
// 发送数据
const char* message = "Hello from client!";
nl_ipc_client_send(client, message, strlen(message));
// 保持连接
while (1) {
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
// 清理
nl_ipc_client_disconnect(client);
nl_ipc_client_destroy(client);
nl_ipc_shutdown();
return 0;
}#include "netleaf_ipc.h"
#include <stdio.h>
int main() {
// === 平台检测 ===
if (!nl_ipc_is_available()) {
printf("ERROR: IPC module is not available on this platform!\n");
printf("Supported platforms: Windows, Linux\n");
printf("Unsupported: macOS\n");
return 1;
}
// === 初始化 ===
int init_result = nl_ipc_init();
if (init_result != 0) {
printf("ERROR: Failed to initialize IPC module (code: %d)\n", init_result);
return 1;
}
// === 创建服务器 ===
#ifdef _WIN32
const char* path = "\\\\.\\pipe\\my_app";
#else
const char* path = "/tmp/my_app_ipc";
#endif
nl_ipc_server_t* server = nl_ipc_server_create(path);
if (!server) {
printf("ERROR: Failed to create IPC server\n");
nl_ipc_shutdown();
return 1;
}
// === 启动服务器 ===
int start_result = nl_ipc_server_start(server);
if (start_result != 0) {
printf("ERROR: Failed to start IPC server (code: %d)\n", start_result);
nl_ipc_server_destroy(server);
nl_ipc_shutdown();
return 1;
}
printf("IPC server started successfully on: %s\n", path);
// ... 业务逻辑 ...
// === 清理 ===
nl_ipc_server_stop(server);
nl_ipc_server_destroy(server);
nl_ipc_shutdown();
return 0;
}路径格式:\\.\pipe\<pipe_name>
// 正确格式
const char* path = "\\\\.\\pipe\\my_pipe_name";
// 命名规则:
// - 管道名称不能包含反斜杠
// - 最大长度为 256 字符
// - 推荐使用字母、数字和下划线路径格式:文件系统路径
// 正确格式
const char* path = "/tmp/my_socket";
const char* path = "/var/run/my_app.sock";
// 注意事项:
// - 路径必须指向可写目录
// - 需要适当的文件系统权限
// - 建议使用 /tmp 或 /var/run 目录IPC模块采用线程安全设计:
| 特性 | 说明 |
|---|---|
| 互斥锁保护 | 内部使用互斥锁保护共享资源 |
| 并发连接 | 支持多客户端并发连接 |
| 回调线程 | 数据回调在独立线程中执行 |
| 线程安全API | 所有公开API均可从多个线程调用 |
| 错误码 | 含义 |
|---|---|
0 |
成功 |
-1 |
通用错误 |
-2 |
平台不支持 |
-3 |
内存分配失败 |
-4 |
无效参数 |
-5 |
连接失败 |
-6 |
发送失败 |
-7 |
服务器未启动 |
NL_MODULE_INFO_BEGIN(ipc, NL_MODULE_TYPE_IPC)
NL_MODULE_NAME("IPC")
NL_MODULE_VERSION("2.2.1")
NL_MODULE_DESCRIPTION("Inter-process communication (Windows Named Pipe / Linux Unix Domain Socket)")
NL_MODULE_AUTHOR("508364")
NL_MODULE_PLATFORM(WINDOWS, LINUX)
NL_MODULE_CAPABILITY(NL_MODULE_CAP_IPC_SERVER)
NL_MODULE_CAPABILITY(NL_MODULE_CAP_IPC_CLIENT)
NL_MODULE_INFO_END()if (!nl_ipc_is_available()) {
// 提供替代方案或优雅降级
printf("IPC not available, falling back to TCP\n");
}// 创建时立即初始化,销毁时自动清理
typedef struct {
nl_ipc_server_t* server;
} AppContext;
AppContext* app_create() {
AppContext* ctx = malloc(sizeof(AppContext));
ctx->server = nl_ipc_server_create("/tmp/my_app");
return ctx;
}
void app_destroy(AppContext* ctx) {
if (ctx->server) {
nl_ipc_server_stop(ctx->server);
nl_ipc_server_destroy(ctx->server);
}
free(ctx);
}// 避免无限等待
int result = nl_ipc_client_connect_with_timeout(client, 5000); // 5秒超时void on_status_changed(int connected, void* user_data) {
if (!connected) {
// 尝试重新连接或通知上层
printf("Disconnected, attempting reconnect...\n");
}
}// Windows Named Pipe 路径限制
// 最大路径长度:256 字符
// 管道名称最大长度:256 - 9 = 247 字符(减去 "\\\\.\\pipe\\")
// Linux Unix Domain Socket 路径限制
// 最大路径长度:通常为 108 字符(依赖于系统)A: IPC 模块不支持 macOS。建议使用 TCP/IP socket 作为跨平台替代方案:
// 使用 TCP socket 实现跨平台进程间通讯
nl_server_t* server = nl_server_create(NL_PROTO_TCP, 12345);A:
- 最大长度:256 字符(包括
\\.\pipe\前缀) - 不能包含反斜杠
- 推荐使用字母、数字和下划线
A: 是的。服务器停止时会自动删除 socket 文件,但如果程序异常退出,可能需要手动清理:
rm /tmp/netleaf_ipcA: IPC 模块天然支持双向通讯。服务端和客户端都可以发送和接收数据:
// 服务端发送
nl_ipc_server_send_to(server, client, data, len);
// 客户端发送
nl_ipc_client_send(client, data, len);