Libevent 事件过滤器

#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;
}



和客户端通信 结果
服务器:
在这里插入图片描述
客户端:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值