libevent实现信号处理
/*
* Compile with:
* cc -I/usr/local/include -o signal-test \
* signal-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <event2/event-config.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <sys/queue.h>
#include <unistd.h>
#include <sys/time.h>
#else
#include <winsock2.h>
#include <windows.h>
#endif
#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <event2/event.h>
int called = 0;
/************************************
@ Brief: 捕获信号事件的回调
@ Author:
@ Created:
@ Return:
************************************/
static void signal_cb(evutil_socket_t fd, short event, void *arg)
{
struct event *signal = arg;
printf("signal_cb: got signal %d\n", event_get_signal(signal));
if (called >= 2)
event_del(signal);
called++;
}
int main(int argc, char **argv)
{
struct event *signal_int;
struct event_base* base;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void) WSAStartup(wVersionRequested, &wsaData);
#endif
/* Initalize the event library */
//初始化信号集合,管理base
base = event_base_new();
/* Initalize one event */
//创建这个事件处理,也可以使用event_new处理
signal_int = evsignal_new(base, SIGINT, signal_cb, event_self_cbarg());
//绑定集合里面
event_add(signal_int, NULL);
//进入事件循环处理
event_base_dispatch(base);
FREE:
event_free(signal_int);
event_base_free(base);
return (0);
}
libevent实现定时的处理
/*
* XXX This sample code was once meant to show how to use the basic Libevent
* interfaces, but it never worked on non-Unix platforms, and some of the
* interfaces have changed since it was first written. It should probably
* be removed or replaced with something better.
*
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <event2/event-config.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <sys/queue.h>
#include <unistd.h>
#endif
#include <time.h>
#ifdef EVENT__HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>
#ifdef _WIN32
#include <winsock2.h>
#endif
struct timeval lasttime;
int event_is_persistent;
static void
timeout_cb(evutil_socket_t fd, short event, void *arg)
{
struct timeval newtime, difference;
struct event *timeout = arg;
double elapsed;
evutil_gettimeofday(&newtime, NULL);
evutil_timersub(&newtime, &lasttime, &difference);
elapsed = difference.tv_sec +
(difference.tv_usec / 1.0e6);
printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
(int)newtime.tv_sec, elapsed);
lasttime = newtime;
if (! event_is_persistent) {
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(timeout, &tv);
}
}
int main(int argc, char **argv)
{
struct event timeout;
struct timeval tv;
struct event_base *base;
int flags;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void)WSAStartup(wVersionRequested, &wsaData);
#endif
if (argc == 2 && !strcmp(argv[1], "-p")) {
event_is_persistent = 1;
flags = EV_PERSIST;
} else {
event_is_persistent = 0;
flags = 0;
}
/* Initalize the event library */
base = event_base_new();
/* Initalize one event */
//创建这个事件处理
event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout);
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(&timeout, &tv);
evutil_gettimeofday(&lasttime, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
event_base_dispatch(base);
return (0);
}
libevent实现Tcp Server基于bufferevent实现
#include <iostream>
#include <string.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/listener.h>
#ifdef _WIN32
#include <windows.h>
#include <time.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#endif
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib, "libevent.lib")
#pragma comment(lib, "libevent_core.lib")
#pragma comment(lib, "libevent_extras.lib")
using namespace std;
/************************************
@ Brief: 读缓冲区回调
@ Author:
@ Created:
@ Return:
************************************/
void read_cb(struct bufferevent *bev, void *arg)
{
char buf[1024] = {0};
char* ip = (char*)arg;
bufferevent_read(bev, buf, sizeof(buf));
cout << "client " << ip << " say:" << buf << endl;
//写数据给客户端
const char *p = "i am server, i received your msg!" ;
bufferevent_write(bev, p, strlen(p)+1);
}
/************************************
@ Brief: 写缓冲区回调
@ Author:
@ Created:
@ Return:
************************************/
void write_cb(struct bufferevent *bev, void *arg)
{
cout << "I'm 服务器,成功写数据给客户端,写缓冲回调函数被调用..." << endl;
}
/************************************
@ Brief: 事件回调
@ Author:
@ Created:
@ Return:
************************************/
void event_cb(struct bufferevent *bev, short events, void *arg)
{
char* ip = (char*)arg;
if (events & BEV_EVENT_EOF)
{
cout << "connection closed:" << ip << endl;
}
else if (events & BEV_EVENT_ERROR)
{
cout << "some other error !" << endl;
}
bufferevent_free(bev);
cout << "bufferevent 资源已经被释放..." << endl;
}
/************************************
@ Brief: 监听回调
@ Author:
@ Created:
@ Return:
************************************/
void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr)
{
struct sockaddr_in* client = (sockaddr_in*)addr ;
cout << "connect new client: " << inet_ntoa(client->sin_addr) << "::"<< ntohs(client->sin_port)<< endl;
struct event_base *base = (struct event_base*)ptr;
//添加新事件
struct bufferevent *bev;
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
//给bufferevent缓冲区设置回调
bufferevent_setcb(bev, read_cb, write_cb, event_cb, inet_ntoa(client->sin_addr));
//启动 bufferevent的 读缓冲区。默认是disable 的
bufferevent_enable(bev, EV_READ);
}
int main()
{
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void)WSAStartup(wVersionRequested, &wsaData);
#endif
//init server
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(8888);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
//创建 event_base
struct event_base * base;
base = event_base_new();
//创建套接字
//绑定
//接收连接请求
struct evconnlistener* listener;
listener = evconnlistener_new_bind(base, cb_listener, base, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 36, (struct sockaddr*)&serv, sizeof(serv));
//启动循环监听
event_base_dispatch(base);
evconnlistener_free(listener);
event_base_free(base);
return 0;
}