版本: 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不会释放,网上有人说没必要,因为即将退出程序,没必要回收,所以尚未找到“优雅”的退出方式。
参考资料: