libevent7: bufferevent 过滤器

和大多过滤器一样,就是在发送前后,做一层处理。代码如下,详情看注释

git地址:http://121.4.70.4:3000/adminPyf/libevent_study.git
libevent_study/test_bufffer_filter

#include <iostream>
#include <event2/event.h>
#include <event2/thread.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <string.h>
#ifdef _WIN32

#else
#include <signal.h>
#endif // !_WIN32

using namespace std;

#define SPORT 5001

bufferevent_filter_result filter_in(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t dst_limit,
                                    enum bufferevent_flush_mode mode, void *ctx)
{
    cout << "filter_in" << endl;
    //读取并清理原数据
    char data[1024] = {0};
    int len = evbuffer_remove(src,data,sizeof(data)-1);

    //将所有转为大写
    for(int i=0;i < len ;i++){
        data[i] = toupper(data[i]);
    }

    evbuffer_add(dst,data,len);
    return BEV_OK;
}

bufferevent_filter_result filter_out(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t dst_limit,
                                     enum bufferevent_flush_mode mode, void *ctx)
{
    cout << "filter_out" << endl;

        //读取并清理原数据
    char data[1024] = {0};
    int len = evbuffer_remove(src,data,sizeof(data)-1);

    string str = "";
    str += "==================\n";
    str += data;
    str += "==================\n";

    evbuffer_add(dst,str.c_str(),str.size());

    return BEV_OK;
}

void read_cb(bufferevent *bev ,void *arg){
    cout << "read_cb" << endl;
    char data[1024] = {0};
    int len = bufferevent_read(bev,data,sizeof(data)-1);
    cout << data << endl;

    //回复客户端消息,经过输出过滤器
    bufferevent_write(bev,data,len);

}

void write_cb(bufferevent *bev ,void *arg){
    cout << "write_cb" << endl;
}

void event_cb(bufferevent *bev ,short events ,void *arg){
    cout << "event_cb" << endl;
}

void listen_cb(struct evconnlistener *e, evutil_socket_t s, struct sockaddr *a, int socklen, void *arg)
{
    std::cout << "listen to be" << std::endl;
    //创建bufferevent 绑定bufferevent filter
    event_base *base = (event_base *)arg;
    bufferevent *bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE);
    bufferevent *bev_filter = bufferevent_filter_new(bev,
                                                     filter_in,
                                                     filter_out,
                                                     BEV_OPT_CLOSE_ON_FREE,
                                                     0,
                                                     0);

    //设置bufferevent回调
    bufferevent_setcb(bev_filter,read_cb,write_cb,event_cb,NULL);
    //设置bufferevent属性
    bufferevent_enable(bev_filter,EV_READ|EV_WRITE);
}

int main()
{
#ifdef _WIN32
    //初始化socket库
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#else
    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
    { //忽略管道信号,发送数据给已关闭的socket,会飞掉!
        return 1;
    }
#endif

    //初始化libevent上下文
    event_config *conf = event_config_new();

    //windows中支持IOCP(线程池) 要查看该项是否开启成功,可以在运行程序后打开任务管理器查看线程数量
#ifdef _WIN32
    event_config_set_flag(conf, EVENT_BASE_FLAG_STARTUP_IOCP);
    evthread_use_windows_threads();
    //设置cpu数量
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    event_config_set_num_cpus_hint(conf, si.dwNumberOfProcessors);
#endif

    //初始化配置上下文
    event_base *base = event_base_new_with_config(conf);

    if (!base)
    {
        cout << "event_base_new_with_config failed!" << endl;
        base = event_base_new();
        if (!base)
        {
            cerr << "event_base_new failed" << endl;
            return 0;
        }
    }
    else
    {
        sockaddr_in sin;
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_port = htons(SPORT);

        evconnlistener *ev = evconnlistener_new_bind(base,                                      //libevent上下文
                                                     listen_cb,                                 //接收到连接的回调函数
                                                     base,                                      //回调函数获取的参数(根据业务来)
                                                     LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, //地址重用,evconnlistener关闭同时关闭socket
                                                     10,                                        //连接队列大小,对应listen函数参数
                                                     (sockaddr *)&sin,                          //绑定的地址和端口
                                                     sizeof(sin));
        event_base_dispatch(base);
        event_base_free(base);
        evconnlistener_free(ev);

        event_config_free(conf);
    }
    return 0;
}

libevent7: bufferevent 过滤器

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动到顶部