zoukankan      html  css  js  c++  java
  • 学习笔记之libevent

    #include "libevent_t.h"
    
    /*************************************************************************
    创建人:LYK        创建时间:2019/05/2 13:41
    IDE: vs2013         库版本:32位 静态库
    
    注意事项:
    1,使用 libevent库时需添加一下附加依赖项
        ws2_32.lib;
        wsock32.lib;        --socket所需要的库
    
        libevent.lib;
        libevent_core.lib;
        libevent_extras.lib;
    
    2、在遇到编译库的问题时,可以用在网上找找库的使用方法,以及自己编译库试试
    **************************************************************************/
    int libevent_t::libevent_init() { #ifdef _WIN32 WSADATA wsa_data; WSAStartup(0x0201, &wsa_data); #endif //创建event_base 事件的集合,多线程的话 每个线程都要初始化一个event_base struct event_base *base; base = event_base_new(); if (!base) { fprintf(stderr, "Could not initialize libevent! "); return 1; } struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); struct evconnlistener *listener; //对socket bind listen accept四个步骤的封装 listener = evconnlistener_new_bind(base,
                            listener_cb,
                            (void *)base,                    LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
                            -1,                    (struct sockaddr*)&sin,                     sizeof(sin)); if (!listener) { fprintf(stderr, "Could not create a listener! "); return 1; } //创建一个事件,类型为持久性EV_PERSIST,回调函数为signal_cb(主要用于监听连接进来的客户端) //将base_ev传递到do_accept中的arg参数 struct event *signal_event; signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); //注册事件,使事件处于 pending的等待状态 if (!signal_event || event_add(signal_event, NULL) < 0) { fprintf(stderr, "Could not create/add a signal event! "); return 1; } //事件循环 ,如何能让循环停止? event_base_dispatch(base); evconnlistener_free(listener); event_free(signal_event); //销毁event_base event_base_free(base); printf("done "); return 0; }

    static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) { struct event_base *base = (event_base *)user_data; struct bufferevent *bev; bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); if (!bev) { fprintf(stderr, "Error constructing bufferevent!"); event_base_loopbreak(base); return; } bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL); bufferevent_enable(bev, EV_WRITE); bufferevent_disable(bev, EV_READ); bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); } static void conn_writecb(struct bufferevent *bev, void *user_data) { struct evbuffer *output = bufferevent_get_output(bev); if (evbuffer_get_length(output) == 0) { printf("flushed answer "); bufferevent_free(bev); } } static void conn_eventcb(struct bufferevent *bev, short events, void *user_data) { if (events & BEV_EVENT_EOF) { printf("Connection closed. "); } else if (events & BEV_EVENT_ERROR) { } /* None of the other events can happen here, since we haven't enabled * timeouts */ bufferevent_free(bev); } static void signal_cb(evutil_socket_t sig, short events, void *user_data) { struct event_base *base = (event_base *)user_data; struct timeval delay = { 2, 0 }; printf("Caught an interrupt signal; exiting cleanly in two seconds. "); event_base_loopexit(base, &delay); }
    libevent库的接口使用流程总结:
    
    //初始化:使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
    WSADATA wsa_data;
    WSAStartup(0x0201, &wsa_data);
    
    //创建event_base 事件的集合,多线程的话 每个线程都要初始化一个event_base
    base = event_base_new();
    
    //对socket bind listen accept四个步骤的封装
    listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
    LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
    (struct sockaddr*)&sin,
    sizeof(sin));
    
    //创建一个事件,类型为持久性EV_PERSIST,回调函数为signal_cb(主要用于监听连接进来的客户端) 
    //将base_ev传递到do_accept中的arg参数 
    struct event *signal_event;
    signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
    
    //注册事件,使事件处于 pending的等待状态
    event_add(signal_event, NULL) ;
     
    //事件循环 ,如何能让循环停止?
    event_base_dispatch(base);
    
    evconnlistener_free(listener);
    event_free(signal_event);
    //销毁event_base
    event_base_free(base);

     问题:

    1、为什么会有两个回调函数?

    2、事件循环如何停止?

  • 相关阅读:
    Detect loop in a singly linked list
    Partition an array around an interger
    Binary search for the first element greater than target
    Searching in a rotated and sorted array
    where, group by, having
    [scalability] Find all documents that contain a list of words
    [DP] 堆盒子问题
    cocos2dx 内存管理的理解
    cocos2dx 2.x版本:简化提炼tolua++绑定自定义类到lua中使用
    OpenGl从零开始之坐标变换(下)
  • 原文地址:https://www.cnblogs.com/luoyankuan/p/10811941.html
Copyright © 2011-2022 走看看