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笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值