libevent tcp API整理
1.01 分配并且返回一个新的具有默认设置的 event_base
struct event_base *base = event_base_new();
// 运行循环
int event_base_dispatch(struct event_base *base);
// 停止循环
int event_base_loopexit(struct event_base *base, const struct timeval *tv);
int event_base_loopbreak(struct event_base *base);
1.02 创建复杂的event_base
struct event_config * cfg = event_config_new(void);
struct event_base * base = event_base_new_with_config(cfg);
event_config_free(cfg);
// 检查 event_base 支持哪些特征
const char **methods = event_get_supported_methods();
printf("Starting Libevent %s. Available methods are:\n", event_get_version());
for (int i=0; methods[i] != NULL; ++i) {
printf(" %s\n", methods[i]);
}
1.03 创建基于套接字的bufferevent
struct bufferevent *bufferevent_socket_new(
struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options
);
// crate
struct bufferevent *bev_ = bufferevent_socket_new(event_base_, socket_, BEV_OPT_CLOSE_ON_FREE);
// free
bufferevent_free(bev_);
1.04 evutil_inet_pton
sockaddr_in svrAddr;
memset(&svrAddr, 0, sizeof(svrAddr));
svrAddr.sin_family = AF_INET;
svrAddr.sin_port = htons(port_);
evutil_inet_pton(AF_INET, addr_ip_.c_str(), &svrAddr.sin_addr.s_addr);
1.05 在bufferevent上启动链接
//[0成功, -1失败]
int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *address, int addrlen);
1.06 基于bufferevent设置回调
// 设置回调函数
bufferevent_setcb(bev_, ReadEventCb_, WriteEventCb_, EventCb_, pData);
// 设置读写事件生效
bufferevent_enable(bev_, EV_READ | EV_WRITE);
1.07 基于过滤的bufferevent设置回调
struct bufferevent * bufferevent_filter_new(struct bufferevent *bev,
bufferevent_filter_cb input_filter,
bufferevent_filter_cb output_filter,
int options,
void (*free_context)(void *),
void *ctx
);
bufferevent_filter_result FilterReadEventCb_(
evbuffer *src,
evbuffer *dst,
ev_ssize_t limit,
bufferevent_flush_mode mode,
void *data
)
bufferevent_filter_result FilterWriteEventCb_(
evbuffer *src,
evbuffer *dst,
ev_ssize_t limit,
bufferevent_flush_mode mode,
void *data
)
bufferevent_filter_result FilterReadEventCb_(evbuffer *src, evbuffer *dst, ev_ssize_t limit,
bufferevent_flush_mode mode, void *data)
{
char buffer[1024] = {0};
int len = evbuffer_remove(src, buffer, sizeof(buffer) - 1);
// todo
evbuffer_add(dst, tmp.c_str(), tmp.size());
return BEV_OK;
}
bufferevent *FilterEvent = bufferevent_filter_new(bev_, FilterReadEventCb_, FilterWriteEventCb_, BEV_OPT_CLOSE_ON_FREE, 0, 0);
bufferevent_setcb(FilterEvent, ReadEventCb_, WriteEventCb_, EventCb_, pData);
bufferevent_enable(FilterEvent, EV_READ | EV_WRITE);
1.08 基于bufferevent设置事件
// 持久事件
timeval t1 = {5, 0};
event *ev_timer = event_new(event_base_, socket_, EV_PERSIST, TimerLoop, pData);
event_add(ev_timer, &t1);
1.09 读/写/异常 事件
void EventCb_(struct bufferevent *bev, short events, void *data)
{
if (events & BEV_EVENT_EOF){}
else if (events & BEV_EVENT_ERROR){
evutil_socket_t socket = bufferevent_getfd(bev);
evutil_closesocket(socket_);
}
else if (events & BEV_EVENT_TIMEOUT){}
else if (events & BEV_EVENT_CONNECTED){}
}
void ReadEventCb_(struct bufferevent *bev, void *data)
{
evutil_socket_t socket = bufferevent_getfd(bev);
int input_size = evbuffer_get_length(bufferevent_get_input(bev_));
int output_size = evbuffer_get_length(bufferevent_get_output(bev_));
int len = bufferevent_read(bev, buf, sizeof(buf));
}
void WriteEventCb_(struct bufferevent *bev, void *data)
{
printf("仅通知--------数据已发送\n");
}
int Write2EventBuffer(struct bufferevent *bev, const char *buf, int len)
{
evutil_socket_t socket = bufferevent_getfd(bev);
bufferevent_write(socket, buf, len);
}
1.10 连接监听
struct evconnlistener *evconnlistener_new_bind(struct event_base *base,evconnlistener_cb cb, void *ptr, unsigned flags,
int backlog, const struct sockaddr *sa, int socklen);
void evconnlistener_free(struct evconnlistener *lev);
struct evconnlistener *listener_ = evconnlistener_new_bind(event_base_, ListenerCb_, pData,
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, socket_, (struct sockaddr *)&sin, sizeof(sin));
void ListenerCb_(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *client_addr, int socklen, void *data)
{
STData *pData = (STData *)data;
char ip[20] = {0};
evutil_inet_ntop(AF_INET, &client_addr, ip, sizeof(ip) - 1);
struct event_base *base = evconnlistener_get_base(listener);
if (base)
{
struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
if (bev)
{
bufferevent_setcb(bev, ReadEventCb_, WriteEventCb_, EventCb_, pNetSession);
bufferevent_enable(bev, EV_READ | EV_WRITE);
printf("new client connect...");
}
}
}