1. 程式人生 > 其它 >Libevent 事件過濾器

Libevent 事件過濾器

技術標籤:libeventlinux

#include "event2/listener.h"
#include <error.h>
#include <string.h>
#include "event.h"
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <event2/bufferevent.h>
#include <event2/bufferevent_struct.h>
#include <event2/buffer.h> #include <event2/util.h> #include <ctype.h> //回撥函式(*bufferevent_filter_cb) bufferevent_filter_cb filter_in(struct evbuffer *evs, struct evbuffer *evd, ev_ssize_t limit, enum bufferevent_flush_mode mode, void* arg) { int i; printf("filter_in\n"
); char data[1024]={0}; //讀取並清理原資料 int len=evbuffer_remove(evs,data,sizeof(data)-1); for( i=0;i<len;i++) { data[i]=toupper(data[i]); } evbuffer_add(evd,data,len); return BEV_OK; } bufferevent_filter_cb filter_out(struct evbuffer *evs, struct evbuffer *evd, ev_ssize_t limit,
enum bufferevent_flush_mode mode, void* arg) { printf("filter_out\n"); char data[1024]={0}; int len=evbuffer_remove(evs,data,sizeof(data)-1); evbuffer_add(evd,data,len); return BEV_OK; } //typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx); void write_cb(struct bufferevent *bev, void *ctx) { printf("write_cb\n"); /* 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. { printf("read_cb\n"); char buf[1024]={0}; //int fd=*(int *)ctx; size_t ret=bufferevent_read(bev,buf,sizeof(buf)); if(ret<0) { perror("read error"); exit(1); }else bufferevent_write(bev,buf,ret); } //有異常發生的回撥函式 //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); } //filter struct bufferevent *bev_filter=bufferevent_filter_new(bufferev, (bufferevent_filter_cb)filter_in, (bufferevent_filter_cb)filter_out, BEV_OPT_CLOSE_ON_FREE, 0,//清理的回撥函式 0); bufferevent_setcb(bev_filter,read_cb,write_cb,event_cb,NULL); //使能bufferevent物件 bufferevent_enable(bev_filter,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; }

和客戶端通訊 結果
伺服器:
在這裡插入圖片描述
客戶端:
在這裡插入圖片描述