libevent学习.1

版本: 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. 了解libeventlibevent是一个开源的事件通知库,它提供了事件驱动的网络编程接口,可以用于开发高性能的网络服务器和客户端应用。它支持多种I/O模型(包括基于事件的和多线程的),并提供了跨平台的兼容性。 2. 安装libevent:你可以从libevent的官方网站(https://libevent.org/)上下载最新版本的libevent,并按照官方文档中的指南进行安装。根据你使用的操作系统不同,安装步骤可能会有所不同。 3. 学习libevent的基本概念:了解libevent中的一些核心概念,如事件循环(event loop)、事件处理器(event handler)、事件回调函数(event callback)等。理解这些概念对于正确使用libevent非常重要。 4. 掌握libevent的使用方法:学习如何使用libevent来编写网络应用程序。这包括创建事件循环、注册事件、定义事件回调函数等。libevent提供了丰富的API,你可以根据自己的需求选择合适的接口进行开发。 5. 深入研究libevent的高级特性:学习libevent的更高级功能,如定时器、信号处理、缓冲区管理等。这些功能可以帮助你更好地控制和优化你的网络应用。 6. 查阅文档和示例代码:libevent的官方网站提供了详细的文档和示例代码,你可以利用这些资源来加深对libevent的理解。此外,还可以参考一些开源项目中使用libevent的实际案例,以便更好地应用于自己的项目中。 记住,学习任何新的库或工具都需要有耐心和实践。不断尝试和练习,结合实际项目,才能更好地掌握和应用libevent。祝你学习顺利!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值