0


linux入门到精通-第二十章-bufferevent(开源高性能事件通知库)

目录

参考

视频教程
libevent的基本使用
libevent–bufferevent的使用与实现

bufferevent简单介绍

一般通过libevent进行网络编程,都是将一个socket的fd与一个event进行绑定,并自行维护一个buffer用于存储从socket上接收的数据,同时可能也用于待发送数据的缓存。然后通过可读可写事件从socket上收取数据写入缓存并进行相应处理,或者将缓存中的数据通过socket发送。

libevent为这种带缓存的IO模式提供了一种通用的机制,那就是bufferevent。一个bufferevent包含了一个底层传输的fd(通常为socket),一个输入buffer和一个输出buffer,并且bufferevent已经帮我们完成了从socket上接收数据写入输入buffer,同时从输出buffer中取出数据通过socket发送,当输入输出缓存中的数据达到一定量时调用我们设置的回调函数。这样使得我们可以更加关注数据的处理。

event_base既可以监听event事件,也可以监听bufferevent事件

event:普通事件,文件描述符,事件(底层缓冲区的读事件或者写事件)触发 回调
bufferevent:高级event事件,bufferevent事件

工作流程

在这里插入图片描述

事件

  • BEV_EVENT_READING 在读操作的时候,触发了一个事件。参考其他标识用来查看是哪个事件。
  • BEV_EVENT_WRITING 在写的时候触发了事件,参考其他标识查看是哪个事件。
  • BEV_EVENT_ERROR 在bufferevent操作时触发了错误。调用EVUTIL_SOCKET_ERROR()获取更多信息。
  • BEV_EVENT_TIMEOUT 超时
  • BEV_EVENT_EOF 触发了end-of-file标识
  • BEV_EVENT_CONNECTED 完成了连接请求。

Api

新建事件节点 bufferevent_socket_new

structbufferevent*bufferevent_socket_new(structevent_base*base,evutil_socket_t fd,enumbufferevent_options options);

参数:
    base:根节点
    fd:要初始化上树的文件描述符
    enumbufferevent_options options:
        BEV_OPT_CLOSE_ON_FREE :释放 bufferevent 时关闭底层传输端口。这将关闭底层套接字,释放底层 bufferevent 等。
        BEV_OPT_THREADSAFE :自动为 bufferevent 分配锁,这样就可以安全地在多个线程中使用 bufferevent。
        BEV_OPT_DEFER_CALLBACKS :设置这个标志时, bufferevent 延迟所有回调,如上所述。
        BEV_OPT_UNLOCK_CALLBACKS :默认情况下,如果设置 bufferevent 为线程安全 的,则 bufferevent 会在调用用户提供的回调时进行锁定。设置这个选项会让 libevent 在执行回调的时候不进行锁定。
返回值:
    新建节点的地址

设置事件节点回调bufferevent_setcb

// 读写回调函数typedefvoid(*bufferevent_data_cb)(structbufferevent*bev,void*ctx);// 事件回调函数typedefvoid(*bufferevent_event_cb)(structbufferevent*bev,short events,void*ctx);voidbufferevent_setcb(structbufferevent*bufev,
bufferevent_data_cb readcb, bufferevent_data_cb writecb,
bufferevent_event_cb eventcb,void*cbarg);

参数:
    bufev:新建节点的地址
    readcb:读回调 从底层缓冲区拷贝到应用缓冲区
    writecb:写回调
    eventcb:异常回调
    cbarg:传给回调函数的参数
    

voidbufferevent_getcb(structbufferevent*bufev,
bufferevent_data_cb *readcb_ptr,
bufferevent_data_cb *writecb_ptr,
bufferevent_event_cb *eventcb_ptr,void**cbarg_ptr);

使事件势能bufferevent_enable

voidbufferevent_enable(structbufferevent*bufev,short events);voidbufferevent_disable(structbufferevent*bufev,short events);shortbufferevent_get_enabled(structbufferevent*bufev);

发送数据bufferevent_write

// 向bufferevent的输出缓冲区添加数据intbufferevent_write(structbufferevent*bufev,constvoid*data,size_t size);intbufferevent_write_buffer(structbufferevent*bufev,structevbuffer*buf);

功能:这些函数向 bufferevent 的输出缓冲区添加数据。 bufferevent_write()将内存中从 data 处开 始的 size 字节数据添加到输出缓冲区的末尾 。bufferevent_write_buffer()移除 buf 的所有内 容,将其放置到输出缓冲区的末尾。成功时这些函数都返回 0,发生错误时则返回-1。

接收数据bufferevent_read

从bufferevent的输入缓冲区移除数据

size_tbufferevent_read(structbufferevent*bufev,void*data,size_t size);intbufferevent_read_buffer(structbufferevent*bufev,structevbuffer*buf);

这些函数从 bufferevent 的输入缓冲区移除数据。bufferevent_read()至多从输入缓冲区移除 size 字节的数据,将其存储到内存中 data 处。函数返回实际移除的字节数。 bufferevent_read_buffer()函数抽空输入缓冲区的所有内容,将其放置到 buf 中,成功时返 回0,失败时返回 -1。

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

evconnlistener的简介

参考:Libevent之evconnlistener详解
用户仅仅需要通过evconnlistener_new_bind传递回调函数,在aceept成功后,在回调函数里面处理已连接的套接字即可。省去了用户需要处理的一些列麻烦问题。
evconnlistener其实是对even_base和event的封装而已。


创建套接字 绑定 监听 提取
structevconnlistener*evconnlistener_new_bind(structevent_base*base,evconnlistener_cb cb,void*ptr,unsigned flags,int backlog,conststructsockaddr*sa,int socklen);
参数:
    base: base根节点
    cb: 提取cfd后调用的回调
    ptr: 传给回调的参数
    flags .
        LEV_OPT_LEAVE SOCKETS BLOCKING 文件描述符为阻塞的
        LEV_OPT_CLOSE ON FREE关闭时自动释放
        LEV_OPT_REUSEABLE 端口复用
        LEV_OPT_THREADSAFE 分配锁,线程安全
    backlog:-1
    sa:绑定地址信息
返回:
    连接侦听器的地址

//一系列的工作函数,因为listener可以用于不同的协议。structevconnlistener_ops{int(*enable)(structevconnlistener*);int(*disable)(structevconnlistener*);void(*destroy)(structevconnlistener*);void(*shutdown)(structevconnlistener*);evutil_socket_t(*getfd)(structevconnlistener*);structevent_base*(*getbase)(structevconnlistener*);};//一层一层封装,加上隔离structevconnlistener{conststructevconnlistener_ops*ops;//操作函数void*lock;//锁变量,用于线程安全
    evconnlistener_cb cb;//用户的回调函数
    evconnlistener_errorcb errorcb;//发生错误时的回调函数void*user_data;//回调函数的参数,当回调函数执行时候,通过形参传入回调函数内部unsigned flags;//属性标志 ,例如socket套接字属性,可以是阻塞,非阻塞,reuse等。short refcnt;//引用计数unsigned enabled :1;//位域为1.即只需一个比特位来存储这个成员 };structevconnlistener_event{structevconnlistener base;structevent listener;//内部event,插入到event_base,完成监听};
标签: linux 开源 运维

本文转载自: https://blog.csdn.net/Blueeyedboy521/article/details/131239900
版权归原作者 Blueeyedboy521 所有, 如有侵权,请联系我们删除。

“linux入门到精通-第二十章-bufferevent(开源高性能事件通知库)”的评论:

还没有评论