libevent学习.1

原创 2017年01月03日 04:46:06

版本: 2.0.22

ECHO服务器(单线程异步例子)

#include <stdlib.h>
#include <string> // C++
#include <string.h> // C
#include <unistd.h>
#include <event.h>
#include <evutil.h>
#include <event2/listener.h>

void cb_read(struct bufferevent *bev, void *ctx) {
    evbuffer *input, *output;
    input = bufferevent_get_input(bev);
    output = bufferevent_get_output(bev);

    char *str = evbuffer_readln(input, NULL, EVBUFFER_EOL_CRLF);
    if (str == NULL) {
        return;
    }

    if (strcmp(str, "bye") == 0) {
        bufferevent_free(bev);
    } else if (strcmp(str, "exit") == 0) {
        event_base *base = bufferevent_get_base(bev);

        // memory leak (had pending bufferevent)
        event_base_loopexit(base, NULL);
    } else {
        std::string s(str);

        s.insert(0, "resp: ");
        s.append("\n");
        bufferevent_write(bev, s.data(), s.size());
    }
    free(str);
}

void cb_write(struct bufferevent *bev, void *ctx) {

}

void cb_error(struct bufferevent *bev, short what, void *ctx) {

    bufferevent_free(bev);
}

void cb_accept(evconnlistener *lev, evutil_socket_t fd, sockaddr *sa, int socklen, void *ctx) {
    event_base *base = evconnlistener_get_base(lev);

    bufferevent *bufev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bufev, cb_read, cb_write, cb_error, NULL);
    bufferevent_enable(bufev, EV_PERSIST|EV_READ|EV_WRITE);
}

void cb_accept_error(evconnlistener *lev, void *ctx) {
    event_base *base = evconnlistener_get_base(lev);

    event_base_loopexit(base, NULL);
}

int do_server(u_short port) {
    event_base *base = event_base_new();
    if (base == NULL) {
        return -1;
    }

    sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl(0);
    sa.sin_port = htons(port);

    evconnlistener *lev = evconnlistener_new_bind(base, cb_accept, NULL, 
        LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1/*BACKLOG*/,
        (sockaddr *)&sa, sizeof(sa));
    if (lev == NULL) {
        event_base_free(base);
        return -2;
    }
    evconnlistener_set_error_cb(lev, cb_accept_error);

    event_base_dispatch(base);

    evconnlistener_free(lev);
    event_base_free(base);
    return 0;
}

int main() {
    return do_server(1256);
}

已知问题:

服务器主动退出事件循环时,与event_base关联的bufferevent不会释放,网上有人说没必要,因为即将退出程序,没必要回收,所以尚未找到“优雅”的退出方式。

参考资料:

Libevent学习笔记(一):基本使用

libevent 接收TCP连接

libevent-2.0.21笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

libevent学习笔记1:牛刀小试

libevnet学习笔记11.   Libevent是什么?Libevent是一个轻量级的开源的高性能的网络库,被众多的开源项目使用,例如大名鼎鼎的memcached等。具有如下的显著的特点:事件驱动...

boost_1_64_0和libevent-2.1.8

  • 2017年08月06日 18:34
  • 67.79MB
  • 下载

libevent官方文档 Ref1-9

  • 2017年02月08日 23:09
  • 2.41MB
  • 下载

libevent代码阅读(1)

一些概念: 1、libevent是一个高性能的io框架,基于Reactor模式 2、event_base即Reactor实例 3、event是事件处理器(注意event不是事件,而是事件处理器) 4...

libevent-1.4.13-1.x86_64.rpm

  • 2011年05月26日 09:27
  • 112KB
  • 下载

libevent-1_4-2-1.4.14b-2.1.x86_64.rpm

  • 2013年07月03日 14:35
  • 72KB
  • 下载

Libevent(1)— 简介、编译、配置

此文编写的时候,使用到的 Libevent 为 2.0.21 Libevent 之跨平台 在处理大量 SOCKET 连接时,使用 select 并不高效。各个系统都提供了处理大量 SOCK...
  • abcd1f2
  • abcd1f2
  • 2015年01月27日 00:17
  • 817

libevent-1.4.13-1.el6.x86_64.rpm

  • 2012年01月16日 17:13
  • 66KB
  • 下载

使用Libevent常用的API搭建一个回显服务器[1]

上一篇讲了Libevent一些常用的API,但是没有实际的demo,多多少少有点难理解,那么接下来就直接上代码 client--one #include #include #include #in...

libevent源码分析(1)--2.1.8--标志信息

一、事件类型标志 event-internal.h /** * @name event flags * * Flags to pass to event_new(), event_ass...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:libevent学习.1
举报原因:
原因补充:

(最多只允许输入30个字)