当前位置: 代码迷 >> 综合 >> Linux网络编程——开源库 libevent
  详细解决方案

Linux网络编程——开源库 libevent

热度:48   发布时间:2023-10-30 14:25:25.0

一、基础介绍

libevent库:开源。精简。跨平台(Windows、Linux、macos、unix)。专注于网络通信。libevent-1.4.14    最旧版的适合学习,代码比较基础libevent-2~			新版的,加了很多新东西,较难理解,不适合看源码。

官网链接

二、源码安装(参考 README文件)

1.安装
put C:\Soft\libevent-2.1.12-stable.tar.gz /root/usr/local/src	# 上传tar -zxvf libevent-2.1.12-stable.tar.gz 	# 解压cd libevent-2.1.12-stable  #进入压缩目录./configure		# 配置make			# 编译sudo make install	# 安装2.测试# 进入sample目录
cd libevent-2.1.12-stable/sample# gcc 编译
gcc hello-world.c -o hello-world -levent	#hello-world.c 本质是一个服务器,输出给客户端 hello world# 执行
./hello-world# 另起一个中端 执行 ,显示出 hello world
nc 127.0.0.1 9995
  1. ./configure 出错
    在这里插入图片描述
    解决方案:

    ubuntu 平台 sudo apt install libssl-dev
    
  2. make 出错
    在这里插入图片描述解决方案:

    sudo proxychains apt-get install python3.8 #安装python,python3 --version #查看是否已装python3
    python --version  #查看是否已装pythonwhereis python3 #查找python3的安装位置:
    whereis python #查找python的安装位置:#系统自带的脚本会以/usr/bin/python的方式直接调用老版本的python,如未安装低版本python就用下面方法建立软连接
    sudo ln -s /usr/bin/python3 /usr/bin/python #创建python3 的软连接到 python
    
  3. ./hello-world 出错
    在这里插入图片描述
    解决方案:

    #将没找到的 libevent-2.1.so.7 库软连接到 ldd 默认扫描的目录 /usr/lib 下
    sudo ln -s /usr/local/lib/libevent-2.1.so.7 /usr/lib/libevent-2.1.so.7
    

三、libevent框架——基础

	libevent 基于 “事件” 异步通信模型。 --- 主要是利用回调机制
  1. libevent 框架基础

    #include <event2/event.h>1.创建 event_basestruct event_base *event_base_new(void);struct event_base *base = event_base_new();2.创建 事件event(两种)常规事件 event --> event_new();  //常规事件 不带缓冲区(不常用)bufferevent	--> bufferevent_socket_new() //带缓冲区的事件 (常用)3.将事件 添加到 event_base 上int event_add(struct event *ev, const struct timeval *tv)4.循环监听事件满足	//启动循环 若满足绑定的事件 就触发常用:int event_base_dispatch(struct event_base *base); //持续循环 若满足事件就触发成功: 0, 失败: -1.只有event_new() 中指定了 EV_PERSIST 才持续触发,否则只触发一次就跳出循环。通常:EV_WRITE | EV_PERSIST、EV_READ|EV_PERSIST不常用:int event_base_loopexit(struct event_base *base,const struct timeval *tv);//在指定时间后停止循环,但在规定时间内仍循环触发int event_base_loopbreak(struct event_base *base);	//立即停止循环5.释放 event_baseevent_base_free();
    
  2. 相关函数(了解即可)

    const char **event_get_supported_methods(void);	//查看支持哪些多路I/O,返回的是数组const char * event_base_get_method(const struct event_base *base); //查看当前用的 多路I/Oint event_reinit(struct event_base *base); //fork()后用来重新初始化子进程中父进程的event_bade,这样父进程创建的 base 才能在子进程中生效。成功:0,失败: -1.
    

    相关函数demo

四、libevent框架——常规事件

  1. 常规事件

    	1.创建事件struct event *ev;struct event *event_new(struct event_base *base, evutil_socket_t fd, short what, event_callback_fn cb, void *arg);1)PARAMETER:base	:event_base_new()返回值fd		:绑定到 event 的文件描述符what	:对应的事件(r、w、e)EV_READ		一次 读事件EV_WRITE	一次 写事件EV_PERSIST	持续触发。结合 event_base_dispatch 函数使用,生效。cb		:一旦事件满足监听条件,回调的函数。typedef void (*event_callback_fn)(evutil_socket_t fd, short, void *)arg		:回调函数的参数2)RETURN VALUE成功创建的 event.2.事件的添加、摘下、销毁int event_add(struct event*ev, const struct timeval *tv);	//添加事件到 event_baseev	:event_new()的返回值。创建事件函数的返回值tv	:NULL,不会超时。等待事件被触发,就调用回调函数非0,等待期间,检查事件没有被触发,时间到,回调函数依旧会被调用。int event_del(struct event *ev);	//从 event_base 上摘下事件ev	:event_new() 的返回值。创建事件函数的返回值int event_free(struct event *ev);	//销毁event_new()创建的事件ev	:event_new() 的返回值。创建事件函数的返回值
    

    常规事件的 未决态 和 非未决态:
    在这里插入图片描述

    常规事件demo

五、libevent框架——带缓冲区事件及网络通信

  1. 带缓冲区事件

    带缓冲区事件裂解里截图理解图:带缓冲区事件裂解里截图理解图

    	#include <event2/bufferevent.h>1.创建 缓冲区事件 bufferevent	//和常规event相比,创建时未直接设置回调函数struct bufferevent *ev;struct bufferevent *bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,enum bufferevent_options options);1)PARAMETERbase	:event_basefd		:封装到bufferevent内的 fdoptions	:BEV_OPT_CLOSE_FREE //释放bufferevent 时关闭底层传输端口。关闭底层套接字,释放底层bufferevent等。2)REATURN VALUE成功创建的 bufferevent 事件对象。2.释放 buffereventvoid bufferevent_free(struct bufferevent *bev);bev		:bufferevent_socket_new 的返回值。3.给 bufferevent 设置回调void bufferevent_setcb(struct bufferevent *bufev,bufferevent_data_cb readcb,bufferevent_data_cb writecb,bufferevent_event_cb eventcb, void *cbarg);1)PARAMETERbufev	:bufferevent_socket_new()函数的返回值。readcb	:读缓冲对应的回调,自己封装,在其内部读数据。【注意】使用bufferevent——read()读,而不是read()。			writecb	:写缓冲对应的回调,不用的话,传 NULL 即可。//给调用者发送写成功通知。eventcb	:设置其他事件回调。可传 NULLcbarg	:上述回调函数用的参数2)回调函数定义: 	1.bufferevent_data_cb //writecb 、readcb 读写回调typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short events,void *ctx)1)PARAMETERbev		:创建的 bufferevent。events	:不同标志位,代表不同的事件。EV_EVENT_READING	:读取操作时发生某事件,具体是哪种事件,看其他标志。BEV_EVENT_WRITING	:写入操作时发生某事件,具体是哪种事件请看其他标志。BEV_EVENT_ERROR		:操作时发生错误。关于错误的更多信息,调用 EVUTIL_SOCKET_ERROR()。BEV_EVENT_TIMEOUT	:发生超时。BEV_EVENT_EOF		:遇到文件结束指示。【常用】	BEV_EVENT_CONNECTED	:请求的连接已完成,实现客户端时可用。【常用】2)应用void read_cb(struct bufferevent *bev, void *ctx){
          ......bufferevent_read()	//读数据,类似 read()bufferevent_write()	//写数据,类似 write()}3)bufferevent_read()bufferevent_write()原型:size_t bufferevent_read(struct bufferevent *bufev,void *data, size_t size);int bufferevent_write(struct bufferevent *bufev, const void *data, size_t size);2.bufferevent_event_cb //eventcb回调typedef void (*bufferevent_event_cb)(struct bufferevent *ev, short events, void *ctx);1)PARAMETER和上述 bufferevent_event_cb 的一致。4.禁用、启用缓冲区默认:新建的 bufferevt 【写缓冲是 enable的】。而, 【读缓冲是disable的】。void bufferevent_enable(struct bufferevent *bufev, short events);	//启用缓冲区, 通常用来启用 bufferenvet 的 read 缓冲。void bufferevent_disable(struct bufferevent *bufev,short events);	//禁用events	:EV_READ、EV_WRITE、EV_READ|EV_WRITEshort bufferevent_get_enabled(struct bufferevent *bufev);	//获取缓冲区禁用状态,借助 & 操作。
    
  2. 带缓冲区事件的网络通信

    1. 客户端连服务器int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *address,int addrlen);bev			:bufferevent 事件对象(封装了 fd)address、len:等同于 connect()的参232. 服务器创建监听器#include <event2/listener.h> //千万别忘了这个1struct evconnlistener * evconnlistener_new(struct event_base *base , evconnlistener_cb cb , void *ptr,unsigned flags, int backlog, evutil_socket_t fd);		//不常用,了解即可2struct evconnlistener *evconnlistener_new_bind(struct event_base *base,evconnlistener_cb cb,void *ptr, unsigned flags, int backlog,const struct sockaddr *sa, int socklen);		//相当于socket()、bind()、listen()、accept()的作用。1.PARAMETERbase	: 创建的 event_base 的返回值cb		:回调函数ptr		:回调函数的参数flags	:可识别的标志。	可以用 | 设置多个。LEV_OPT_CLOSE_ON_FREE	//释放 bufferevent 时关闭底层传输端口。LEV_OPT_REUSEABLE		//端口复用。backlog	:listen()2-1 代表最大值。sa		:服务器自己的地址结构体len		:服务器自己的结构体的大小2.RETURN VALUE成功:创建的监听器。3evconnlistener_new_bind()中回调函数类型typedef void (*evconnlistener_cb)(struct evconnlistener *listener, evutil_socket_t sock, struct sockaddr *addr, int len,void *ptr) listener	:evconnlistener_new_bind()的返回值sock		:用于通信的文件描述符addr		:客户端的IP + 端口len			:addr 的 lenptr			:外部 ptr 传递进来值//回调函数由框架自行调用。3.释放创建的监听器void evconnlistener_free(struct evconnlistener *lev); //释放创建的监听器