最近使用开发的进程中出现了一个小问题,顺便记录一下原因和方法--事件循环

基于libevent实现了一个简单的echoclient。之前在网上看到的都是echoserver。这里演示一下使用libevent进行客户端编程的基本步调。

先看代码:

#include "stdafx.h"
#include "event2/event.h"
#include "event2/util.h"#define ECHO_PORT   8888
#define ECHO_SERVER "127.0.0.1"struct echo_context{struct event_base *base;struct event *event_write;struct event *event_read;const char * echo_contents;int echo_contents_len;int recved;
};void write_cb(evutil_socket_t sock, short flags, void * args)
{struct echo_context *ec = (struct echo_context *)args; int ret = send(sock, ec->echo_contents, ec->echo_contents_len, 0);printf("connected, write to echo server: %d\n", ret);event_add(ec->event_read, 0);
}void read_cb(evutil_socket_t sock, short flags, void * args)
{struct echo_context *ec = (struct echo_context *)args; char buf[128];int ret = recv(sock, buf, 128, 0);printf("read_cb, read %d bytes\n", ret);if(ret > 0){ec->recved += ret;buf[ret] = 0;printf("recv:%s\n", buf);}else if(ret == 0){printf("read_cb connection closed\n");event_base_loopexit(ec->base, NULL);return;}if(ec->recved < ec->echo_contents_len){event_add(ec->event_read, 0);}
}static evutil_socket_t make_tcp_socket()
{int on = 1;evutil_socket_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);evutil_make_socket_nonblocking(sock);
#ifdef WIN32setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, sizeof(on));
#elsesetsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
#endifreturn sock;
}static void echo_client(struct event_base *base)
{evutil_socket_t sock = make_tcp_socket();struct sockaddr_in serverAddr;struct event * ev_write = 0;struct event * ev_read = 0;struct timeval tv={10, 0};struct echo_context *ec = (struct echo_context*)calloc(1, sizeof(struct echo_context));serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(ECHO_PORT);
#ifdef WIN32serverAddr.sin_addr.S_un.S_addr = inet_addr(ECHO_SERVER);
#elseserverAddr.sin_addr.s_addr = inet_addr(ECHO_SERVER);
#endifmemset(serverAddr.sin_zero, 0x00, 8);connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr));ev_write = event_new(base, sock, EV_WRITE, write_cb, (void*)ec);ev_read = event_new(base, sock, EV_READ , read_cb, (void*)ec);ec->event_write = ev_write;ec->event_read = ev_read;ec->base = base;ec->echo_contents = strdup("echo client tneilc ohce\n");ec->echo_contents_len = strlen(ec->echo_contents);ec->recved = 0;event_add(ev_write, &tv);
}int _tmain(int argc, _TCHAR* argv[])
{struct event_base * base = 0;
#ifdef WIN32WORD wVersionRequested;WSADATA wsaData;wVersionRequested = MAKEWORD(2, 2);(void) WSAStartup(wVersionRequested, &wsaData);
#endifbase = event_base_new();echo_client(base);event_base_dispatch(base);event_base_free(base);return 0;
}
每日一道理
即使青春是一枝娇艳的花,但我明白,一枝独放永远不是春天,春天该是万紫千红的世界。 即使青春是一株大地伟岸的树,但我明白,一株独秀永远不是挺拔,成行成排的林木,才是遮风挡沙的绿色长城。即使青春是一叶大海孤高的帆,但我明白,一叶孤帆很难远航,千帆竞发才是大海的壮观。

代码是在windows上实现的。

使用libevent进行客户端编程的基本步调,在《libevent实现http client》中已经提过,基本如下:

  1. 初始化event_base(后续要运行事件循环)
  2. 创立socket,设置为异步,连接server
  3. 创立写读写事件,先将写事件参加事件循环
  4. 在写事件回调中向server端发送请求并将读事件参加事件循环
  5. 在读事件回调中处置数据,并根据数据是不是读取终了决定是不是继续添加读事件

结合本文的示例代码,通过event_base_new()创立event_base,在初始化客户端socket(echo_client)之后,调用event_base_dispatch运行事件循环。

echo_client函数初始化了socket,设置为非阻塞模式,调用connect连接到echoserver,然后添加一个写事件到事件循环中。当连接成功后,会触发写事件。这里将write_cb作为写事件的回调,在调用event_new()时传入。

write_cb()写入一个字符串,然后添加一个读事件,在读事件中读取echoserver的回应。

基本的进程就是这模样了。这是个简单的例子,更庞杂的例子,基本流程也是一样的。

文章结束给大家分享下程序员的一些笑话语录: 问路
有一个驾驶热气球的人发现他迷路了。他降低了飞行的高度,并认出了地面 上的一个人。他继续下降高度并对着那个人大叫,“打扰一下,你能告诉我我 在哪吗?”
下面那个人说:“是的。你在热气球里啊,盘旋在 30 英尺的空中”。
热气球上的人说:“你一定是在 IT 部门做技术工作”。
“没错”,地面上的人说到,“你是怎么知道的?”
“呵呵”,热气球上的人说,“你告诉我的每件事在技术上都是对的,但对都没 有用”。
地面上的人说,“你一定是管理层的人”。
“没错”,热气球上的人说,“可是你是怎么知道的?”
“呵呵”,地面上的那人说到,“你不知道你在哪里,你也不知道你要去哪,你 总希望我能帮你。你现在和我们刚见面时还在原来那个地方,但现在却是我 错了”。

转载于:https://www.cnblogs.com/jiangu66/archive/2013/05/18/3085796.html

事件循环libevent实现echoclient相关推荐

  1. 【Libevent】Libevent学习笔记(三):事件循环

    00. 目录 文章目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. eve ...

  2. 【传智播客】Libevent学习笔记(三):事件循环

    目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. event_base_l ...

  3. c/c++:Libevent应用(Libevent介绍、 事件处理框架 - event_base、事件循环、事件、带缓冲区的事件、链接监听器)

    目录 1. Libevent介绍 1.1 安装Libevent 2. 事件处理框架 - event_base 2.1 event_base API函数 event_base和fork(进程)关系: 3 ...

  4. Libevent 事件循环(1)

    // 事件的dispatch int event_base_loop(struct event_base *base, int flags) { //得到采用的事件模型 epoll/epoll/sel ...

  5. 事件根基event_base、事件循环event_loop、事件event、信号事件SignalEvent

    一.event_base (一) libevent简介与浅谈event_base libevent实际上就是对底层select/poll/epoll等进行了封装,每个event_base都有一种&qu ...

  6. 【转载】浏览器事件循环机制(event loop)

    首先,本文转自https://juejin.im/post/5afbc62151882542af04112d 当我看完菲利普·罗伯茨的 javascript event loop的演讲的时候,就对于事 ...

  7. 原生js循环展示dom_【前端面试】用一道题讲 js 的事件循环队列

    昨天去面了滴滴,一口气面了三面,考了 promise 和事件循环.之前的猿辅导也考察了这些,几乎所有的大厂中厂都一定会考原生 js 的事件循环队列. 今天,我把昨天考察的原题拿出来分析一下. setT ...

  8. boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...

    Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...

  9. JS 总结之事件循环

    众所周知,JavaScript 为了避免复杂,被设计成了单线程. ⛅️ 任务 单线程意味着所有任务都需要按顺序执行,如果某个任务执行非常耗时,线程就会被阻断,后面的任务需要等上一个任务执行完毕才会进行 ...

最新文章

  1. API 网关从入门到放弃
  2. 使用 FOR XML PATH 合并SQL Server查询结果的重复行
  3. style=@android:style/buttonbar,Setting style=?android:attr/buttonBarStyle to parent layout and s...
  4. Array String对象的方法和属性
  5. 关于RT-Thread的背景和成长
  6. 玩转算法之面试第十章-贪心算法
  7. 大厂面试常问的机器学习,计算机视觉怎么学?详细指南来了!
  8. Fiddler V5中文版
  9. 机器人学重点知识点总结
  10. office+visio2016版本一同安装说明
  11. 常用z变换及其收敛域
  12. 我如何用Unity3D实现一个Galgame框架(存档读档与设置面板的思路)
  13. WIN10 VS2019 编译Cyrus SASL
  14. Linux下测试SSD硬盘读写速率
  15. 钟摆小游戏的开发过程
  16. LPN(Request,Offer,Poll / Update,Establish,Cache)
  17. 深度强化学习DQN网络
  18. 计算机网络学习笔记(一)——什么是Internet
  19. 查找——图文翔解Treap(树堆)
  20. 显示器尺寸和分辨率大小

热门文章

  1. [极致用户体验] 网页里的「返回」应该用 history.back 还是 push ?
  2. k8s使用volume将ConfigMap作为文件或目录直接挂载_从应用开发角度认识 K8S
  3. PMP(第六版)中的沟通方法
  4. 如何识别手写汉字?跟着步骤就能完成
  5. 无法搜索到对方电脑共享的文件
  6. String.intern()
  7. java小时钟实验报告_JAVA实验报告(运用JavaFx实现时钟动画).doc
  8. 京杭大运河北线疏浚穿越黄河地形UTM平面直角坐标系分析GIS模型建立
  9. 2.2 法力池的创建和视觉特效———自制卡牌游戏之旅
  10. 【大厂面试】智力题怎么破?