基于socket的bufferevent由一个socket的传输层和read/write buffer组成。区别于常规的event,当socket可读或者可写时会回调用户的callback,bufferevent当读取或者写入足够多的数据到evbuffer后,才回调用户回调函数。这个足够多的数据由水位线(watermarks)定义。

bufferevent四种watermarks:

Read low-water mark
当输入缓存中读入的数据超过这个水位线则触发用户callback回调,默认是0,所以每次读都会导致callback被调用。
Read high-water mark
假如输入缓存中读入的数据超过这个水位线,会disable调读事件,直到输入缓存变小。
Write low-water mark
当输出缓存不高于这个水位线,则触发用户写callback回调。
Write high-water mark
在socket bufferevent中没有使用。

基于socket的buffeevent

源码实现在bufferevent_sock.c中。核心函数描述如下:
bufferevent_socket_new主要是:
1.在常规event基础上设置读写事件callback(bufferevent_readcb, bufferevent_writecb);
2.enable可写事件,使得任何添加到output缓存中的内容能在bufferevent_writecb中写出去;

bufferevent_readcb:

149 if (bufev->wm_read.high != 0) {
150 howmuch = bufev->wm_read.high - evbuffer_get_length(input);
151 /* we somehow lowered the watermark, stop reading */
152 if (howmuch <= 0) { // 如果超过了read high watermark需要disable read event,停止读取socket
153 bufferevent_wm_suspend_read(bufev);
154 goto done;
155 }
156 }
157 readmax = _bufferevent_get_read_max(bufev_p);
158 if (howmuch < 0 || howmuch > readmax) /* The use of -1 for "unlimited"
159 * uglifies this code. XXXX */
160 howmuch = readmax;

_bufferevent_get_read_max返回一次最多读取多少数据,其实是:
#define MAX_TO_READ_EVER 16384
之后就是真正从socket读数据到input buffer中了,函数evbuffer_read从指定fd读取指定字节到指定evbuffer。
socket可写的时候回调bufferevent_writecb,这个函数主要是吧output buffer中的数据写出去,每次写也有个最大字节数限制:
#define MAX_TO_WRITE_EVER 16384
evbuffer_write_atmost便是把output buffer中的数据发送出去的功能函数,总的来说写和读比较对称,首先都是操作一个buffer,读的时候是增大input buffer,写的时候是清空output buffer,写的时候有一个细节,每次写完判断output buffer是否为空,如果空了就disable write event,这时为了防止没必要的可写事件唤醒浪费CPU时间。

bufferevent的缓冲区evbuffer

bufferevent使用的buffer都是一种叫做evbuffer的数据结构,定义在evbuffer-internal.h,总的来说是一段一段连续内存被链表串起来的结构,每一段内存又叫做evbuffer_chain。(待续。。。)

libevent之基于socket的bufferevent的更多相关文章

  1. libevent笔记6:ssl bufferevent

    Libevent另外提供了基于openssl的bufferevent来支持ssl,通过特殊的ssl bufferevent来对数据进行加密. ps:本文不对openssl相应的接口做介绍因为不熟 SS ...

  2. 基于Socket客户端局域网或广域网内共享同一短信猫收发短信的开发解决方案

    可使同一网络(局域网或广域网)内众多客户端,共享一个短信猫设备短信服务器进行短信收发,短信服务器具备对客户端的管理功能. 下面是某市建设银行采用本短信二次开发平台时实施的系统方案图: 在该方案中,考虑 ...

  3. C#基于Socket的简单聊天室实践

    序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...

  4. memcached基于socket访问memcache缓存服务器

    memcached基于socket访问memcache缓存服务器 操作memcache常用三种方法: .memcache基于php_memcache.dll扩展(php扩展) .memcached基于 ...

  5. MFC 配合 protobuff libevent 实现的Socket 的GM工具 框架

    MFC 配合 protobuff libevent 实现的Socket 的GM工具 框架

  6. 在线白板,基于socket.io的多人在线协作工具

    首发:个人博客,更新&纠错&回复 是昨天这篇博文留的尾巴,socket.io库的使用练习,成品地址在这里. 代码已经上传到github,传送门.可以开俩浏览器看效果. 现实意义是俩人在 ...

  7. Android 基于Socket的聊天应用(二)

    很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...

  8. 基于Socket的UDP发包程序

    UDP(User Datagram Protocol,用户数据报协议)是在互联网中常用的传输层协议,该协议提供了向另一用户程序发送的消息的最简便的协议机制.与TCP一样,其默认的下层协议是IP.UDP ...

  9. Java基于Socket文件传输示例(转)

    最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加 ...

随机推荐

  1. h5问题总结

    一.下拉刷新上拉加载 主要依赖一款插件mescroll.js  http://www.mescroll.com/ 简单好用.以前同事的用法是初始化执行执行上拉会调,页数从0开始,下拉重新加载当前地址走 ...

  2. Selenium多浏览器测试

    在浏览器的兼容性测试中,会测试产品在不同浏览器上的兼容性,比较主流的浏览器有IE.Firefox.Chrome,Opera,Safari等.还有其它如360.QQ.遨游.百度等浏览器都是基于IE或者c ...

  3. SpringBoot+Vue 前后端合并部署

    前后端分离开发项目 前端vue项目 服务端springboot项目 如何将vue的静态资源整合到springboot项目里,通过启动jar包的方式部署服务. 前端项目执行npm run build 命 ...

  4. SM4

    整体结构 T变换 SM4解密的合理性证明 秘钥扩展

  5. 学习Promise异步编程

    JavaScript引擎建立在单线程事件循环的概念上.单线程( Single-threaded )意味着同一时刻只能执行一段代码.所以引擎无须留意那些"可能"运行的代码.代码会被放 ...

  6. Reset 对象属性

    Input Reset 对象 在 HTML 表单中 标签每出现一次,一个 Reset 对象就会被创建. 当重置按钮被点击,包含它的表单中所有输入元素的值都重置为它们的默认值.默认值由 HTML val ...

  7. 多线程写法,消除同步bug

    public class Demo01 implements Runnable { private int ticket = 10; @Override public void run() { for ...

  8. vue中的插值操作

    mustache语法 1.将data的文本数据插入至html语句中,使用mustache语法. v-once指令 2.在某些情况下,我们不希望界面随意的跟随改变,这个时候我们可以使用v-once的指令 ...

  9. jupyter安装插件Nbextensions,实现代码提示功能(终极方法)

    jupyter安装插件,实现代码提示功能 第一步 pip install jupyter_contrib_nbextensions -i https://mirrors.tuna.tsinghua.e ...

  10. 结合MATLAB、Python、R语言,在求得显著差异的边(节点对)之后,怎么画circle图

                                                            先来看看成果图: OK,开始画图: 实验背景声明:在脑影像分析中,我们首先构建脑网络,然 ...