#include "libevent_t.h" /************************************************************************* 创建人:LYK 创建时间:2019/05/2 13:41 IDE: vs2013 库版本:32位 静态库 注意事项: 1,使用 libevent库时需添加一下附加依赖项 ws2_32.lib; wsock32.lib; --socket所需要的库 libevent.lib; libevent_core.lib; libevent_extras.lib; 2、在遇到编译库的问题时,可以用在网上找找库的使用方法,以及自己编译库试试 **************************************************************************/
int libevent_t::libevent_init() { #ifdef _WIN32 WSADATA wsa_data; WSAStartup(0x0201, &wsa_data); #endif //创建event_base 事件的集合,多线程的话 每个线程都要初始化一个event_base struct event_base *base; base = event_base_new(); if (!base) { fprintf(stderr, "Could not initialize libevent!\n"); return 1; } struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); struct evconnlistener *listener; //对socket bind listen accept四个步骤的封装 listener = evconnlistener_new_bind(base,
listener_cb,
(void *)base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
-1, (struct sockaddr*)&sin, sizeof(sin)); if (!listener) { fprintf(stderr, "Could not create a listener!\n"); return 1; } //创建一个事件,类型为持久性EV_PERSIST,回调函数为signal_cb(主要用于监听连接进来的客户端) //将base_ev传递到do_accept中的arg参数 struct event *signal_event; signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); //注册事件,使事件处于 pending的等待状态 if (!signal_event || event_add(signal_event, NULL) < 0) { fprintf(stderr, "Could not create/add a signal event!\n"); return 1; } //事件循环 ,如何能让循环停止? event_base_dispatch(base); evconnlistener_free(listener); event_free(signal_event); //销毁event_base event_base_free(base); printf("done\n"); return 0; }
static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) { struct event_base *base = (event_base *)user_data; struct bufferevent *bev; bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); if (!bev) { fprintf(stderr, "Error constructing bufferevent!"); event_base_loopbreak(base); return; } bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL); bufferevent_enable(bev, EV_WRITE); bufferevent_disable(bev, EV_READ); bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); } static void conn_writecb(struct bufferevent *bev, void *user_data) { struct evbuffer *output = bufferevent_get_output(bev); if (evbuffer_get_length(output) == 0) { printf("flushed answer\n"); bufferevent_free(bev); } } static void conn_eventcb(struct bufferevent *bev, short events, void *user_data) { if (events & BEV_EVENT_EOF) { printf("Connection closed.\n"); } else if (events & BEV_EVENT_ERROR) { } /* None of the other events can happen here, since we haven't enabled * timeouts */ bufferevent_free(bev); } static void signal_cb(evutil_socket_t sig, short events, void *user_data) { struct event_base *base = (event_base *)user_data; struct timeval delay = { 2, 0 }; printf("Caught an interrupt signal; exiting cleanly in two seconds.\n"); event_base_loopexit(base, &delay); }
libevent库的接口使用流程总结: //初始化:使用Socket的程序在使用Socket之前必须调用WSAStartup函数。 WSADATA wsa_data; WSAStartup(0x0201, &wsa_data); //创建event_base 事件的集合,多线程的话 每个线程都要初始化一个event_base base = event_base_new(); //对socket bind listen accept四个步骤的封装 listener = evconnlistener_new_bind(base, listener_cb, (void *)base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1, (struct sockaddr*)&sin, sizeof(sin)); //创建一个事件,类型为持久性EV_PERSIST,回调函数为signal_cb(主要用于监听连接进来的客户端) //将base_ev传递到do_accept中的arg参数 struct event *signal_event; signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); //注册事件,使事件处于 pending的等待状态 event_add(signal_event, NULL) ; //事件循环 ,如何能让循环停止? event_base_dispatch(base); evconnlistener_free(listener); event_free(signal_event); //销毁event_base event_base_free(base);
问题:
1、为什么会有两个回调函数?
2、事件循环如何停止?