Libevent
一個(gè)事件集合struct event_base。
一個(gè)事件 struct event (io事件,定時(shí)器事件,信號(hào)事件)。
#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>
//讀事件回調(diào)
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);
}
}
//其他事件回調(diào)
void event_cb(struct bufferevent*bev,short what,void *arg)
{
if(what &BEV_EVNET_EOF)
{
printf("客戶端下線\n");
bufferevent_free(bev); //釋放buffereven對(duì)象
}
else
{
printf("未知錯(cuò)誤");
}
}
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; //需要從主函數(shù)傳遞過來
//針對(duì)已經(jīng)存在的socket創(chuàng)建bufferevent對(duì)象
//參數(shù)如下:返回buffer對(duì)象
struct bufferevent*bev = bufferevent_socket_new(base, //事件集合
fd, //文件描述符
BEV_OPT_CLOSE_ON_FREE //釋放bufferevent對(duì)象則斷開連接
);
//給bufferevnet設(shè)置回調(diào)函數(shù)
bufferevent_setcb(bev, //buffereven對(duì)象
read_cb, //讀回調(diào)
NULL, //寫回調(diào)
event_cb, //其他回調(diào)
(void*)fd; //參數(shù)
//使能事件類型
bufferevent_enable(bev, //buffereven對(duì)象
EV_READ //使能讀
)
}
int main()
{
//創(chuàng)建一個(gè)事件集合
struct event_base *base = event_base_new();
if(NULL==base)
{
exit(1);
}
//創(chuàng)建監(jiān)聽對(duì)象
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");
//一步完成:創(chuàng)建socket 綁定socket,監(jiān)聽,接受鏈接四部
//參數(shù)如下:
struct evconnlistener *listener = evconnlistener_new_bind(base, //事件集合
listener_cb, //當(dāng)有鏈接時(shí)調(diào)用的函數(shù)
NULL, //回調(diào)函數(shù)的參數(shù)
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
10, //監(jiān)聽隊(duì)列的長度
(struct sockaddr*)&server_addr, //tcp綁定信息
sizeof(server_addr) //tcp信息的大小
);
if(NULL == listener)
{
exit(1);
}
//監(jiān)聽集合中的事件
event_base_dispatch(base);
//釋放兩個(gè)對(duì)象
evconnlistener_free(listener); //連接對(duì)象
event_base_free(base); //釋放集合
}