#include "event2/listener.h"
#include <error.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
//回调函数
void listencallback(struct evconnlistener *a1, evutil_socket_t fd, struct sockaddr *addr, int socklen,void *arg)
{
printf("callbcak\n");
}
int main(int argc, char *argv[])
{
/*socket bind listen accept*/
//用 evconnlistener_new_bind一步到位
/*
//配置参数
* struct evconnlistener *evconnlistener_new_bind(struct event_base *base,
evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
const struct sockaddr *sa, int socklen);*/
struct event_base *base=event_base_new(); // chuang jian ji he
if(base==NULL)
{
perror("base create error");
exit(1);
}
// evconnlistener_cb cb ----------- 当一个新的连接到达就会调用回调函数
// void *ptr -----回调函数的参数
//unsigned flags ------------默认为NULL
// LEV_OPT_LEAVE_SOCKETS_BLOCKING 阻塞等待
//LEV_OPT_CLOSE_ON_FREE 释放监听对象的时候关闭sokcet
// LEV_OPT_REUSEABLE socket 关闭的时候端口可以重复使用
//int backlog----监听队列长度
struct sockaddr_in server;
memset(&server,0,sizeof(server));
server.sin_port=ntohs(8888);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
server.sin_family=AF_INET;
//释放监听对象关闭soket |端口重复使用
//sockt fd 会加到集合base中去
struct evconnlistener *evlisten=evconnlistener_new_bind(base,listencallback,
NULL,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,10,(struct sockaddr*)&server,sizeof(server));
if(evlisten==NULL)
{
perror("evconnlistener_new_bind error");
exit(1);
}
printf(" accept success\n");
//监听
event_base_dispatch(base);
// 释放 对象
evconnlistener_free(evlisten);
//释放集合
event_base_free(base);
return 0;
}
#include "event2/listener.h"
#include <error.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
#include "event2/bufferevent.h"
//回调函数
//typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);
void write_cb(struct bufferevent *bev, void *ctx)
{
char buf[128];
fgets(buf,sizeof(buf),stdin);
int ret=bufferevent_write(bev,buf,strlen(buf));
if(ret==0)
{
printf("write success\n");
}
}
void read_cb(struct bufferevent *bev, void *ctx) // @return 0 if successful, or -1 if an error occurred.
{
char buf[128]={0};
int fd=*(int *)ctx;
size_t ret=bufferevent_read(bev,buf,sizeof(buf));
if(ret<0)
{
perror("read error");
exit(1);
}else printf("read from %d data: %s",fd,buf);
}
//有异常发生的回调函数
//typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx);
void event_cb(struct bufferevent *bev, short what, void *ctx)
{
printf("what!!! %x\n",what);
if(what&BEV_EVENT_EOF)
{
printf("客户端%d下线\n",*(int *)ctx);
bufferevent_free(bev);//释放bufferevent 对象
}else
{
printf("未知错误\n");
}
}
void listencallback(struct evconnlistener *evlisten, evutil_socket_t fd, struct sockaddr *addr, int socklen,void *arg)
{
printf("callbcak\n");
//针对 异常存在的 sockket创建 bufferevent 对象
/*struct bufferevent *bufferevent_socket_new(struct event_base *base,
* evutil_socket_t fd, int options);
*/
struct event_base *base =arg;
//如果bufferevent 对象 被释放 就关闭文件描述符
// BEV_OPT_CLOSE_ON_FREE ruguo bufferevent dui xiang bei shifang jiu guan bi wen jian miao shu fu
//BEV_OPT_THREADSAFE
//BEV_OPT_DEFER_CALLBACKS
//BEV_OPT_UNLOCK_CALLBACKS
struct bufferevent *bufferev=bufferevent_socket_new(base, fd,BEV_OPT_CLOSE_ON_FREE );
if(bufferev==NULL) {
perror("bufferevent_socket_new error");
exit(1);
}
//bufferevent 设置回调函数
/*
void bufferevent_setcb(struct bufferevent *bufev,
bufferevent_data_cb readcb, ke du
bufferevent_data_cb writecb, ke xie
bufferevent_event_cb eventcb, yichang
void *cbarg);chuan canshu
*/
bufferevent_setcb(bufferev,read_cb,write_cb,event_cb,&fd);
//使能bufferevent对象
bufferevent_enable(bufferev,EV_READ|EV_WRITE);
}
int main(int argc, char *argv[])
{
/*socket bind listen accept*/
//用 evconnlistener_new_bind一步到位
struct event_base *base=event_base_new(); //创建时间集合
if(base==NULL)
{
perror("base create error");
exit(1);
}
// evconnlistener_cb cb ----------- 当一个新的连接到达就会调用回调函数
// void *ptr -----回调函数的参数
//unsigned flags ------------默认为NULL
// LEV_OPT_LEAVE_SOCKETS_BLOCKING 阻塞等待
//LEV_OPT_CLOSE_ON_FREE 释放监听对象的时候关闭sokcet
// LEV_OPT_REUSEABLE socket 关闭的时候端口可以重复使用
//int backlog----监听队列长度
struct sockaddr_in server;
memset(&server,0,sizeof(server));
server.sin_port=ntohs(8888);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
server.sin_family=AF_INET;
//释放监听对象关闭soket |端口重复使用
//sockt fd 会加到集合base中去
struct evconnlistener *evlisten=evconnlistener_new_bind(base,listencallback,
base,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,10,(struct sockaddr*)&server,sizeof(server));
if(evlisten==NULL)
{
perror("evconnlistener_new_bind error");
exit(1);
}
printf(" accept success\n");
//监听
event_base_dispatch(base);
// 释放 对象
evconnlistener_free(evlisten);
//释放集合
event_base_free(base);
return 0;
}
//监听端口
// struct evconnlistener *evlisten= evconnlistener_new_bind(base,
// callbcak,//接收到连接的回调函数
// base,//回调函数获取的参数
// LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,//地址重用 listen关闭同时清理socket
// 10,//链接队列大小 对应Listen
// (struct sockaddr*)&addr,
// sizeof(addr) );