Libevent
一个事件集合struct event_base。
一个事件 struct event (io事件,定时器事件,信号事件)。
#include <stdio.h>
#include <stdlib.h>
#include <event.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <event2/listener.h>
//读事件回调
void read_cb(struct bufferevent*bev,void *arg)
{
int fd = *(int*)arg;
char buf[128] = 0;
int ret = bufferevent_read(bev, buf, sizeof(buf));
if(ret < 0)
{
printf("read error\n");
}
else
{
printf("recv from %d:%s",fd,buf);
}
}
//其他事件回调
void event_cb(struct bufferevent*bev,short what,void *arg)
{
if(what &BEV_EVNET_EOF)
{
printf("客户端下线\n");
bufferevent_free(bev); //释放buffereven对象
}
else
{
printf("未知错误");
}
}
void listener_cb(struct evconnlistener*listener, evutil_socket_t fd,struct sockaddr*addr,int socklen, void *arg)
{
printf("接受%d的连接\n",fd);
struct event_base *base = arg; //需要从主函数传递过来
//针对已经存在的socket创建bufferevent对象
//参数如下:返回buffer对象
struct bufferevent*bev = bufferevent_socket_new(base, //事件集合
fd, //文件描述符
BEV_OPT_CLOSE_ON_FREE //释放bufferevent对象则断开连接
);
//给bufferevnet设置回调函数
bufferevent_setcb(bev, //buffereven对象
read_cb, //读回调
NULL, //写回调
event_cb, //其他回调
(void*)fd; //参数
//使能事件类型
bufferevent_enable(bev, //buffereven对象
EV_READ //使能读
)
}
int main()
{
//创建一个事件集合
struct event_base *base = event_base_new();
if(NULL==base)
{
exit(1);
}
//创建监听对象
struct sockaddr_in server_addr;
memset(&server_addr, 0 ,sizeof(server_addr));
server_addr.sin_port = 8000;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//一步完成:创建socket 绑定socket,监听,接受链接四部
//参数如下:
struct evconnlistener *listener = evconnlistener_new_bind(base, //事件集合
listener_cb, //当有链接时调用的函数
NULL, //回调函数的参数
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
10, //监听队列的长度
(struct sockaddr*)&server_addr, //tcp绑定信息
sizeof(server_addr) //tcp信息的大小
);
if(NULL == listener)
{
exit(1);
}
//监听集合中的事件
event_base_dispatch(base);
//释放两个对象
evconnlistener_free(listener); //连接对象
event_base_free(base); //释放集合
}