Linux网络编程——开源库 libevent

51 篇文章 6 订阅
7 篇文章 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  #查看是否已装python
    
    whereis 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_base
    	struct 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_base
    	event_base_free();
    
  2. 相关函数(了解即可)

    const char **event_get_supported_methods(void);	//查看支持哪些多路I/O,返回的是数组
    
    const char * event_base_get_method(const struct event_base *base); //查看当前用的 多路I/O
    
    int 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_base
    					ev	: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)PARAMETER
    			base	:event_base
    			fd		:封装到bufferevent内的 fd
    			options	:BEV_OPT_CLOSE_FREE //释放bufferevent 时关闭底层传输端口。关闭底层套接字,释放底层bufferevent等。
    		2)REATURN VALUE
    			成功创建的 bufferevent 事件对象。
    	
    	2.释放 bufferevent
    		void 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)PARAMETER
    			bufev	:bufferevent_socket_new()函数的返回值。
    			readcb	:读缓冲对应的回调,自己封装,在其内部读数据。
    					【注意】使用bufferevent——read()读,而不是read()。			
    			writecb	:写缓冲对应的回调,不用的话,传 NULL 即可。//给调用者发送写成功通知。
    			eventcb	:设置其他事件回调。可传 NULL
    			cbarg	:上述回调函数用的参数
    				
    		2)回调函数定义: 	
    						1.bufferevent_data_cb //writecb 、readcb	读写回调
    							typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short events,void *ctx)
    								1)PARAMETER
    										bev		:创建的 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_WRITE
    		
    		short 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()的参23
    
    2. 服务器创建监听器
    	#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.PARAMETER
    				base	: 创建的 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 的 len
    			ptr			:外部 ptr 传递进来值
    		//回调函数由框架自行调用。
    		
    3.释放创建的监听器
    	void evconnlistener_free(struct evconnlistener *lev); //释放创建的监听器
    
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值