参考视频链接:服务并发编程-libevent
#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 *ctx)
{
int fd = *(int *) ctx;
char buf{128} = {0};
size_t ret = bufferevent_read(bev,buf,sizeof(buf));
if(ret < 0){
printf("bufferevent_read error!\n");
}else{
printf("read from %d %s\n",fd,buf);
}
}
void event_cb(struct bufferevent *bev, short what, void *ctx)
{
if(what & BEV_EVENT_EOF){
printf("客户端%d下线\n",*(int *)ctx);
bufferevent_free(bev);
}else{
printf("未知错误\n");
}
}
void listener_cb(struct evconnlistener *listener, evutil_sockect_t fd, struct sockaddr *addr, int socklen, void *arg)
{
printf("接受%d的连接\n",fd);
struct event_base *base = arg;
//针对已经存在的socket创建bufferevent对象
//事件集合(从主函数传来)、fd(代表TCP连接)、BEV_OPT_CLOSE_ON_FREE(如果释放bufferevent对象则关闭连接)
struct bufferevent *bev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
if(bev == NULL){
printf("bufferevent_socket_new error!\n");
exit(1);
}
//给bufferevent设置回调函数
//bufferevent对象、读事件回调函数、写事件回调函数、其他事件回调函数、参数
bufferevent_setcb(bev, read_cd, NULL, event_bc, &fd);
//使能bufferevent对象
bufferevent_enable(bev,EV_READ);
}
int main()
{
//创建一个事件集合
struct event_base *base = event_base_new();
if(NULL == base)
{
printf("event_base_new error!\n");
exit(1);
.
}
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = 8000;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//创建socket、绑定、监听、接受连接
//创建监听对象,在指定的地址上监听接下来的TCP连接
//事件集合、当有连接时调用的函数、回调函数参数、释放监听对象socket|端口重复使用、监听队列长度、绑定信息
struct evconnlistener *listner = evconnlistener_new_bind(base,listener_cb,NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
10,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(listner == NULL)
{
printf("evconnlistener_new_bind error!\n");
exit(1);
}
//监听集合中的事件
event_base_dispatch(base);
//释放两个对象
evconnlistener_free(listner);
event_base_free(base);
return 0;
}