环境搭建
由于一开始在Macos上安装lib event遇到了一点小问题,后改用在ubuntu上安装并成功运行事例代码。之后又觉得不能放弃Mac上的环境搭建,于是开始折腾如何安装libevent。
安装C++通用包管理器
vcpkg是一个跨平台的C++包管理器,有了它可以很方便安装各种包
安装vckpg
首先编译安装vcpkg
vcpkg卡在下载Cmake…
使用clashX开启终端代理,成功安装vcpkg
之后
1 2
| ./vcpkg serach libevent ./vcpkg install libevent
|
libevent安装完成
初步使用libevent
封装event_base
libevent存在类似于libcurl中的curl这种全局资源,因此使用RAII对其进行初步封装,以便实现资源的自动管理。
设置evconnlistener
此函数用于设置感兴趣的事件,监听的端口已经base,回掉函数等参数。
回掉函数
由于libevent使用的是C语言,回掉函数的类型其实已经写死了,但是我们可以通过回掉函数设置的参数来传递我们自动的funtion和arg。以下是默认的回掉函数定义
1
| void listen_callback(struct evconnlistener *e, evutil_socket_t s, struct sockaddr * addr, int socklen, void *arg)
|
事件分发
event_base_dispatch
暂时还没看懂这个函数的作用,但是函数参数为event_base*,初步猜测应该是通过event_base来确定分发事件的。
初探代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include <csignal> #include <event2/event.h> #include <event2/listener.h> #include <iostream> #include <memory> #include <functional> #include <future>
#define VNAME(value) (#value)
using namespace std;
template<class T> inline static void error_nullptr(const std::string& str, const T& instance) { if(instance == nullptr) { std::cout<<str<<"failed\n"; exit(0); } }
template<class F,class S> inline static void free_source(F&& fn,S&& arg) { if(arg) fn(arg); arg = nullptr; }
template <class T = int> class Callback { public: template<class A,class ...args> Callback(A&& fn,args&&... arg):f(std::bind(fn,arg...)){} T instance() { return f(); } std::function<T()> f; };
void listen_callback(struct evconnlistener *e, evutil_socket_t s, struct sockaddr * addr, int socklen, void *arg) { std::cout<<reinterpret_cast<Callback<int>*>(arg)->instance()<<std::endl; }
class Base { public: Base(int port,evconnlistener_cb callback,Callback<int>& param): eb_instance(nullptr) { eb_instance = event_base_new(); error_nullptr(VNAME(eb_instance), eb_instance); sockaddr_in sock; memset(&sock,0, sizeof(sock)); sock.sin_family = AF_INET; sock.sin_port = htons(port); ec_listener = evconnlistener_new_bind(eb_instance, callback, (void*)¶m, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 128, (sockaddr*)&sock, sizeof(sock));
error_nullptr(VNAME(ec_listener), ec_listener); event_base_dispatch(eb_instance); } ~Base() { free_source(evconnlistener_free, ec_listener); free_source(event_base_free, eb_instance); } event_base* get_instance() { return eb_instance; } private: event_base* eb_instance; evconnlistener* ec_listener; };
int two_sum(int a,int b) { return a+b; }
int main() { Callback<int>two(two_sum,10,20); std::shared_ptr<Base>bases = std::make_shared<Base>(9999,listen_callback, two); return 0; }
|