news 2026/4/26 0:59:09

zmq源码分析之多 Socket 监听方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
zmq源码分析之多 Socket 监听方案

文章目录

    • 核心方案:使用 zmq_poller
      • 1. 创建 poller
      • 2. 添加 socket 到 poller
      • 3. 等待事件
      • 4. 处理事件
    • 完整示例
      • 监听多个 SUB socket
    • 高级用法
      • 1. 动态管理 socket
      • 2. 非阻塞模式
      • 3. 超时设置
    • 最佳实践
    • 适用场景
    • 总结

当需要连接多个 socket 并同时监听消息时,使用 ZeroMQ 的zmq_poller是最佳选择。

核心方案:使用 zmq_poller

1. 创建 poller

void*poller=zmq_poller_new();

2. 添加 socket 到 poller

// 添加多个 socketzmq_poller_add(poller,socket1,NULL);zmq_poller_add(poller,socket2,NULL);// 可以添加更多 socket...

3. 等待事件

zmq_pollitem_t items[2];// 也可以动态分配items[0].socket=socket1;items[0].fd=0;items[0].events=ZMQ_POLLIN;items[1].socket=socket2;items[1].fd=0;items[1].events=ZMQ_POLLIN;// 等待事件,timeout 为 -1 表示无限等待intrc=zmq_poll(items,2,-1);if(rc==-1){// 处理错误}

4. 处理事件

// 检查哪个 socket 有事件if(items[0].revents&ZMQ_POLLIN){// socket1 有消息charbuffer[1024];zmq_recv(socket1,buffer,sizeof(buffer),0);printf("Received from socket1: %s\n",buffer);}if(items[1].revents&ZMQ_POLLIN){// socket2 有消息charbuffer[1024];zmq_recv(socket2,buffer,sizeof(buffer),0);printf("Received from socket2: %s\n",buffer);}

完整示例

监听多个 SUB socket

#include<zmq.h>#include<stdio.h>intmain(){void*ctx=zmq_ctx_new();// 创建多个 SUB socketvoid*sub1=zmq_socket(ctx,ZMQ_SUB);zmq_connect(sub1,"tcp://localhost:5555");zmq_setsockopt(sub1,ZMQ_SUBSCRIBE,"",0);// 订阅所有消息void*sub2=zmq_socket(ctx,ZMQ_SUB);zmq_connect(sub2,"tcp://localhost:5556");zmq_setsockopt(sub2,ZMQ_SUBSCRIBE,"",0);// 准备 poll itemszmq_pollitem_t items[]={{sub1,0,ZMQ_POLLIN,0},{sub2,0,ZMQ_POLLIN,0}};while(1){intrc=zmq_poll(items,2,-1);if(rc==-1)break;// 中断if(items[0].revents&ZMQ_POLLIN){charbuffer[1024];zmq_recv(sub1,buffer,sizeof(buffer),0);printf("From publisher 1: %s\n",buffer);}if(items[1].revents&ZMQ_POLLIN){charbuffer[1024];zmq_recv(sub2,buffer,sizeof(buffer),0);printf("From publisher 2: %s\n",buffer);}}zmq_close(sub1);zmq_close(sub2);zmq_ctx_term(ctx);return0;}

高级用法

1. 动态管理 socket

// 动态添加 socketvoidadd_socket_to_poller(void*poller,void*socket){zmq_poller_add(poller,socket,NULL);}// 移除 socketvoidremove_socket_from_poller(void*poller,void*socket){zmq_poller_remove(poller,socket);}

2. 非阻塞模式

// 非阻塞,立即返回intrc=zmq_poll(items,2,0);if(rc==0){// 无事件,继续其他工作}

3. 超时设置

// 1000ms 超时intrc=zmq_poll(items,2,1000);if(rc==0){// 超时,做其他事情}

最佳实践

  1. 使用 zmq_poller:单线程处理多 socket,避免线程开销
  2. 合理设置超时:根据应用需求调整
  3. 错误处理:检查所有 ZeroMQ 函数的返回值
  4. 资源管理:正确关闭所有 socket 和 poller
  5. 事件驱动:基于事件处理,提高响应速度

适用场景

  • 多订阅:同时订阅多个 publisher
  • 多客户端:服务器同时处理多个客户端连接
  • 混合模式:同时处理不同类型的 socket(如 SUB + REP)
  • 资源监控:同时监听多个数据源

总结

连接多个 socket 并监听消息的最佳方案

  1. 使用zmq_poller管理多个 socket
  2. 一次等待多个 socket 的事件
  3. 根据事件来源处理不同 socket 的消息
  4. 单线程处理,避免线程复杂性

这种方式比多线程更高效,代码更简洁,是 ZeroMQ 推荐的多 socket 管理方式!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 0:57:04

词级神经语言模型开发实战:从原理到应用

1. 词级神经语言模型开发指南在自然语言处理领域&#xff0c;词级神经语言模型是构建智能文本系统的基石。这类模型通过分析大量文本数据&#xff0c;学习词语之间的概率分布关系&#xff0c;不仅能预测下一个可能出现的单词&#xff0c;还能生成连贯的新文本。我在实际项目中多…

作者头像 李华
网站建设 2026/4/26 0:55:43

OSMO触觉手套:磁感应技术与人机交互革新

1. OSMO触觉手套&#xff1a;重新定义人机交互的触觉接口在机器人操作领域&#xff0c;触觉反馈长期被视为实现人类级别灵巧性的关键瓶颈。想象一下&#xff0c;当你闭着眼睛试图系鞋带时&#xff0c;仅凭手指对绳子的压力感知就能完成整个动作——这正是触觉反馈赋予我们的神奇…

作者头像 李华
网站建设 2026/4/26 0:33:15

云原生入门系列|第12集:K8s日常运维实战,新手也能稳管集群

前言 各位云原生入门的小伙伴,欢迎继续跟进《云原生入门系列》专栏!上一集我们掌握了K8s故障排查的核心方法,能快速定位并解决Pod、Service、存储等常见故障,避免业务中断。 但K8s的运维不止“排查故障”,更重要的是“日常管理”——就像养花草,不仅要在生病时治病,还…

作者头像 李华
网站建设 2026/4/26 0:29:32

JVM 调优实战指南

系列导读&#xff1a;本篇将深入讲解 JVM 调优的核心原理与实战技巧。 文章目录目录一、JVM 内存模型1.1 内存结构1.2 内存参数二、垃圾回收器2.1 GC 对比2.2 G1 配置2.3 ZGC 配置三、调优参数3.1 内存配置3.2 GC 配置3.3 日志配置四、问题诊断4.1 常用工具4.2 OOM 排查4.3 CPU…

作者头像 李华
网站建设 2026/4/26 0:21:53

Agent-C:4KB纯C语言AI智能体,零依赖实现本地Shell命令执行

1. 项目概述&#xff1a;一个极简主义的AI执行者 最近在折腾AI应用本地化部署时&#xff0c;我一直在寻找一个能真正“轻装上阵”的解决方案。市面上的AI Agent框架动辄几百MB&#xff0c;依赖库一大堆&#xff0c;部署起来让人头疼。直到我遇到了Agent-C&#xff0c;一个用纯…

作者头像 李华