当前位置:   article > 正文

bufferevent有关介绍与使用_bufferevent_socket_new

bufferevent_socket_new

带缓冲区的通信:bufferevent

bufferevent由一个底层的传输端口(如套接字),一个读取缓冲区和一个写入缓冲区组成。与通常的事件在底层传输端口已经就绪,可以读取或者写入的时候执行回调不同的是,bufferevent在读取或者写入了足够量的数据之后调用用户提供的回调。

基于套接字的bufferevent是最简单的,它使用libevent的底层事件机制来检测底层网络套接字是否已经就绪,可以进行读写操作,并且使用底层网络调用(如readv、writev、WSASend、WSARecv)来发送和接收数据。


创建/释放套接字bufferevent
1、bufferevent_socket_new()

创建基于套接字的bufferevent,将需要监听的文件描述符fd添加到事件集合base中去。

struct bufferevent * bufferevent_socket_new(
                     struct event_base *base,
                     evutil_socket_t fd,
                     enum bufferevent_options options
);

返回值:
成功:返回一个指向结构体bufferevent的指针,失败则返回NULL
bufferevent也是一个event

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

base是event_base。
fd是一个可选的表示套接字的文件描述符。如果是socket的方法,则socket需要设置为非阻塞模式(在socket()和bind()之间)。如果想以后设置文件描述符,可以设置fd为-1。
options是表示bufferevent选项标志的位掩码。

bufferevent的选项标志:

标志含义
BEV_OPT_CLOSE_ON_FREE释放bufferevent时关闭底层传输端口。这将关闭底层套接字(socket被关闭等),释放底层bufferevent等(一般用这个选项)
BEV_OPT_THREADSAFE自动为bufferevent分配锁,这样就可以安全地在多个线程中使用bufferevent
BEV_OPT_DEFER_CALLBACKS设置这个标志时,bufferevent延迟所有回调,参考时延回调
BEV_OPT_UNLOCK_CALLBACKS默认情况下,如果设置bufferevent为线程安全的,则bufferevent会在调用用户提供的回调时进行锁定。设置这个选项会让libevent在执行回调的时候释放bufferevnt的锁

2、bufferevent_free()
void bufferevent_free(struct bufferevent *bev);
  • 1

这个函数释放bufferevent。
bufferevent内部具有引用计数,所以,如果释放bufferevent时还有未决的延迟回调,则在回调完成之前bufferevent不会被删除。
例子:
如果设置了延时回调BEV_OPT_UNLOCK_CALLBACKS,则释放会在延时回调调用了回调函数之后,才会真正释放。

如果设置了BEV_OPT_CLOSE_ON_FREE标志,并且bufferevent有一个套接字或者底层bufferevent作为其传输端口,则释放bufferevent将关闭这个传输端口。


在基于套接字的bufferevent上启动连接

如果bufferevent的套接字还没有连接上,可以启动新的连接。

接口:

//如果连接启动成功,函数返回0;发生错误则返回-1
int bufferevent_socket_connect(
    struct bufferevent *bev,
    struct sockaddr *address, int addrlen);
  • 1
  • 2
  • 3
  • 4

address和addrlen参数跟标准调用connect()的参数相同。
如果还没有为bufferevent设置套接字,调用函数将为其分配一个新的流套接字,并且设置为非阻塞的
如果已经为bufferevent设置套接字,调用bufferevent_socket_connect()将告知libevent套接字还未连接,直到连接成功之前不应该对套接字进行读取或者写入操作。
连接完成之前可以向输出缓冲区添加数据。


设置bufferevent回调函数和相关设置

使用bufferevent之后,libevent会帮我们托管三种事件:
1、读取事件
2、写入事件
3、处理事件

这三种事件都在回调的函数结构中体现!!

3、在bufferevent上设置回调函数:bufferevent_setcb()
//对bufferevent设置回调函数	
void bufferevent_setcb(
		struct bufferevent *bufev,
		bufferevent_data_cb readcb,     //读取足够的数据时被调用
		bufferevent_data_cb writecb,        //写入足够的数据时被调用		 
        bufferevent_event_cb eventcb, 		
		void *cbarg //共用的传入回调函数的参数
	);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
//读取和写入的回调,其中ctx为通用传递的参数
		typedef void (*bufferevent_data_cb)(
				struct bufferevent *bev, 
				void *ctx
		);
 
//事件回调,即连接断开、错误处理等回调
		typedef void (*bufferevent_event_cb)(
				struct bufferevent *bev,
				short events, 
				void *ctx
		);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

event参数为事件,用户可以在回调函数中拿这个事件来进行事务处理的判断

events参数作用
BEV_EVENT_READING在bufferevent上进行读取操作时出现了一个事件
BEV_EVENT_WRITING在bufferevent上进行写入操作时发生了一个事件
BEV_EVENT_ERROR在bufferevent上操作时发生错误
BEV_EVENT_TIMEOU在bufferevent上发生超时
BEV_EVENT_EOF在bufferevent上遇到文件结束符,连接断开
BEV_EVENT_CONNECTED在bufferevent上请求的连接过程已经完成(实现客户端的时候可以判断)

禁用或启动回调函数
4、bufferevent_enable()/bufferevent_disable()

设置回调函数为启动状态或禁用态:
可以启用或者禁用 bufferevent 上的 EV_READ、EV_WRITE 或者 EV_READ | EV_WRITE 事件。没有启用读取或者写入事件时, bufferevent 将不会试图进行数据读取或者写入。

//开启
		void bufferevent_enable(
			struct bufferevent *bufev, 
			short events
		); 
 
//禁用, 对应的回调就不会被调用
		void bufferevent_disable(
			struct bufferevent *bufev, 
			short events
		); 
 
 
		short bufferevent_get_enabled(
			struct bufferevent *bufev
		); 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

操控bufferevent中的数据
5、bufferevent_write()
int bufferevent_write(
				struct bufferevent *bufev,
				const void *data, 
				size_t size
         //返回值:成功0,失败-1
		);
        
        
int bufferevent_write_buffer(
        struct bufferevent* bufev,
        struct evbuffer* buf);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

bufferevent_write()从bufferevent的输出缓冲区添加(写)数据
将内存中从data处开始的size字节数据添加到输出缓冲区的末尾

bufferevent_write_buffer()移除buf的所有内容,将其放置到输出缓冲区的末尾。
这些函数:成功返回0,发生错误时则返回-1。


6、bufferevent_read()
	  size_t bufferevent_read(
				struct bufferevent *bufev, 
				void *data, 
				size_t size
       );
     
    int bufferevent_read_buffer(
            struct bufferevent* bufev,
            struct evbuffer* buf)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

bufferevent_read()从bufferevent的输入缓冲区移除(读)数据
至多从输入缓冲区移除size字节的数据,将其存储到内存中data处。
返回值:实际移除的字节数。

注意,data处的内存块必须有足够的空间容纳size字节数据。

bufferevent_read_buffer()函数抽空输入缓冲区的所有内容,将其放置到buf中
这些函数:成功时返回0,失败时返回-1。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/534188
推荐阅读
相关标签
  

闽ICP备14008679号