学习笔记之libevent

#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、事件循环如何停止?

转载于:https://www.cnblogs.com/luoyankuan/p/10811941.html

你可能感兴趣的:(学习笔记之libevent)