libevent官网 http://libevent.org/
libevent api http://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html
简单介绍libevent关键api
struct event_base* event_base_new (void)
初始化一个新的事件,但这个不是一个全局事件,如果想使用全局事件,使用event_init(void)
如果使用这个api创建一个新的事件,那么在之后的每次set一个事件之后都需要调用event_set_base()
如果使用event_init(void)则不需要调用event_set_base()
void event_set ( struct event * ,
evutil_socket_t ,
short ,
void(*)(evutil_socket_t, short, void *) ,
void *
);
参数解释
ev an event struct to be modified
fd the file descriptor to be monitored
event desired events to monitor; can be EV_READ and/or EV_WRITE
fn callback function to be invoked when the event occurs
arg an argument to be passed to the callback function
引用的官网api的解释,很容易理解,主要就是事件的类型以及回调函数。
int event_add (struct event * ,const struct timeval * )
添加事件,前一个set的api设置完需要添加到主循环的事件响应里面。
int event_dispatch(void)
启动主消息监听循环。本质上使用的select,epoll这一套,所以需要主循环监听事件。
参考其他人的文章写了一个简单的demo
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <cstring>
#include <event.h>
using namespace std;
void Read(int iCliFd, short iEvent, void *arg) {
int iLen;
char buf[1500];
iLen = recv(iCliFd, buf, 1500, 0);
if (iLen <= 0) {
cout << "Client Close" << endl;
struct event *pEvRead = (struct event*)arg;
event_del(pEvRead);
delete pEvRead;
close(iCliFd);
return;
}
buf[iLen] = 0;
cout << "Client Info:" << buf << endl;
}
void onAccept(int iSvrFd, short iEvent, void *arg) {
int iCliFd;
struct sockaddr_in sCliAddr;
event_base* base = (event_base *)arg;
cout << "in onAccept" << endl; //>>>>
socklen_t iSinSize = sizeof(sCliAddr);
iCliFd = accept(iSvrFd, (struct sockaddr*)&sCliAddr, &iSinSize);
struct event *pEvRead = new event;
event_set(pEvRead, iCliFd, EV_READ|EV_PERSIST, Read, pEvRead);
event_base_set(base, pEvRead);
event_add(pEvRead, NULL);
}
class LVServer {
private:
struct event_base* base;
int serv_sock;
sockaddr_in sCliAddr;
sockaddr_in sSvrAddr;
public:
bool init() {
memset(&sSvrAddr, 0, sizeof(sSvrAddr));
sSvrAddr.sin_family = AF_INET;
sSvrAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sSvrAddr.sin_port = htons(8888);
sSvrAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
if (!serv_sock) return false;
int ret = bind(serv_sock, (struct sockaddr*)&sSvrAddr, sizeof(sSvrAddr));
//if (!ret) return false;
ret = listen(serv_sock, 10); //
//if (!ret) return false;
// can print log.
return true;
}
int start() {
base = event_base_new();
struct event evListen;
event_set(&evListen, serv_sock, EV_READ|EV_PERSIST, onAccept, (void *)base);
event_base_set(base, &evListen);
event_add(&evListen, NULL);
event_base_dispatch(base);
return 0;
}
};
int main() {
LVServer myServer;
int ret = myServer.init();
if (!ret) {
cout << "error in init" << endl;
return -1;
}
return myServer.start();
}