zmq与libevent集成及丢包问题分析解决
来源:互联网 发布:东莞数据恢复 dgfix 编辑:程序博客网 时间:2024/06/04 22:43
libevent与socket使用事件方式进行编程的思路是:以zmq的订阅端为例子,订阅端与服务端的连接的fd(文件描述符)加入到libevent的监听队列中,并传入自己的回调函数。正常情况下,当有数据来的时候,libevent会调用用户传入的回调函数,在回调函数里面去将数据取出来即可。
下面需要解决二个问题:
1、如何取得zmq的socket值?
使用getsockopt函数获取。
zmq::socket_t subscribe;int sock_fd = 0;size_t len = sizeof(sock_fd);subscribe.getsockopt(ZMQ_FD, &sock_fd, &len);
2、丢包问题?
当获得之后,按每秒一个包的情况下,能工作得很好,没有问题。但当你发送频率变得很高,每秒几千之后,则出现丢包情况。
分析原因:在于zmq低层采用的是边缘触发机制。当多个数据到达的时候,触发器只会触发一次。
两种机制的区别,大家可以看这篇blog里面说明的:https://funcptr.net/2012/09/10/zeromq---edge-triggered-notification/
解决方案:
当触发回调的时候,需要一次性把数据全部读完。不要只读一次,否则可能存在你多次数据到来的时候,只通知一次的情况。这样情况下,则会导致数据好像“丢失”了。
int zevents = 0;size_t zevents_len = sizeof(zevents);zmq_socket.getsockopt(ZMQ_EVENTS, &zevents, &zevents_len);if (zevents & ZMQ_POLLIN) { // We can read from the ZeroMQ socket}if (zevents & ZMQ_POLLOUT) { // We can write to the ZeroMQ socket}
#include <iostream>#include <sstream>#include <event.h>#include "log_time.h"#include <zmq.hpp>#include <signal.h>struct event_base* evbase; void OnEvent(zmq::socket_t* sock) { uint32_t events; size_t sz_events = sizeof(events); sock->getsockopt(ZMQ_EVENTS, &events, &sz_events); while(events & ZMQ_POLLIN) { zmq::message_t msg; bool ok = sock->recv(&msg, ZMQ_NOBLOCK); if (!ok) { perror("not ok here, return"); } else { printf("size = %d, msg = %s\n", msg.size(), msg.data()); } sock->getsockopt(ZMQ_EVENTS, &events, &sz_events); } }void pair_callback(int a, short b, void *point) { if (NULL == point) { perror("pair is null, please check you code\n"); return; } zmq::socket_t *sock = (zmq::socket_t *)point; OnEvent(sock);}int main (int argc, char *argv[]){ signal(SIGPIPE, SIG_IGN); zmq::context_t context(1); // Socket to talk to server zmq::socket_t sub_socket(context, ZMQ_SUB); // Subscribe to zipcode, default is NYC, 10001 sub_socket.setsockopt(ZMQ_SUBSCRIBE, "", 0); //subscriber.connect("ipc://weather.ipc"); sub_socket.connect("tcp://localhost:6556"); int sock_fd= 0; size_t len = sizeof(sock_fd); sub_socket.getsockopt(ZMQ_FD, &sock_fd, &len); printf("sock_fd = %d\n", sock_fd); evbase = event_base_new(); printf("event_new\n"); printf("sub_socket = %p\n", &sub_socket); struct event* ev = event_new(evbase, sock_fd, EV_READ|EV_PERSIST, pair_callback, (void*)&sub_socket); event_add(ev, NULL); event_base_dispatch(evbase); return 0;}
阅读全文
0 0
- zmq与libevent集成及丢包问题分析解决
- zmq与libevent共处
- zmq与libevent共处
- 集成QtCreator与Eclipse CDT,及相关问题的解决
- TCP粘包问题的分析与解决
- Eclipse+TestNG+EclEmma集成问题及解决
- IMG与元素边界有空隙问题分析及解决
- TCP通信丢包主要问题及具体问题分析
- 解决网络丢包问题及故障判断方法
- SSH集成实践二:问题与解决
- YARN环境中应用程序JAR包冲突问题的分析及解决
- TCP粘包问题分析和解决
- UDP主要丢包原因及具体问题分析
- UDP主要丢包原因及具体问题分析
- UDP主要丢包原因及具体问题分析
- UDP主要丢包原因及具体问题分析
- UDP主要丢包原因及具体问题分析
- UDP之丢包原因及具体问题分析
- jzoj100023 【NOIP2016提高A组模拟7.6】塔
- Draggabilly中文文档
- 1018. 锤子剪刀布 (20)
- getchar()
- 版本管理之gitlab实践教程:基础篇(8)
- zmq与libevent集成及丢包问题分析解决
- 单应矩阵 基本矩阵 本质矩阵的区别与联系
- xcode反汇编调试iOS模拟器程序(一)查看反汇编
- Java对日期Date类进行加减运算,年份加减,月份加减
- Android 自定义 View 开发
- 机器学习笔记之模型表述
- 实验五 JPEG解码
- 银联商务MISPOS接口开发demo 需要调用POSINF.DLL
- 机器学习笔记二十三 TensorFlow