bufferevent中提供了对读写回调的触发条件及最大缓存长度的设置,即低高水位:

  • 低水位:是读写回调函数的最低触发数据长度,当输入/输出缓存区中的数据长度小于低水位时,读/写回调函数不会被触发;
  • 高水位:是缓存区的最大接收长度,当输入/输出缓存区中的数据长度大于高水位时,不会继续向缓存区中增加数据。

水位设置函数bufferevent_setwatermark

void bufferevent_setwatermark (struct bufferevent *bufev, short events, size_t lowmark, size_t highmark)

该函数能够为一个给定的bufferevent设置指定事件的低高水位。若events为EV_READ则为设置读回调函数的水位;events为EV_WRITE则为设置写回调函数的水位,

Demo

服务端:在创建了与客户端连接的bufferevent后,设置低水位为6,高水位为10。

//server.c
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <event2/buffer.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h> // 读缓冲区回调
void read_cb(struct bufferevent *bev, void *arg)
{
char buf[1024] = {0};
bufferevent_read(bev, buf, sizeof(buf));
//这里不能直接输出字符串
for(int i = 0; i < 20; ++i)
{
printf("%c", buf[i]);
}
printf("\n");
} void cb_listener(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int len, void *ptr){ struct sockaddr_in *addr_in = (struct socketaddr*)addr;
printf("connect new client from: %s\n", inet_ntoa(addr_in->sin_addr));
struct event_base* base = (struct event_base*)ptr;
// 通信操作
// 添加新事件
struct bufferevent *bev;
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // 给bufferevent缓冲区设置回调
bufferevent_setcb(bev, read_cb, NULL, NULL, NULL);
bufferevent_enable(bev, EV_READ);
bufferevent_enable(bev, EV_WRITE); //设置读写的高低水位
bufferevent_setwatermark(bev, EV_READ|EV_WRITE, 6, 10);
} int main(int argc, const char* argv[])
{
// init server
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(9995);
serv.sin_addr.s_addr = htonl(INADDR_ANY); struct event_base* base;
base = event_base_new();
// 创建套接字
// 绑定
// 接收连接请求
struct evconnlistener* listener;
listener = evconnlistener_new_bind(base, cb_listener, base,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
36, (struct sockaddr*)&serv, sizeof(serv)); event_base_dispatch(base);
evconnlistener_free(listener);
event_base_free(base);
return 0;
}

客户端:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <event2/event.h>
#include <event2/bufferevent.h> void send_cb(evutil_socket_t fd, short what, void *arg)
{
char buf[1024] = {0};
struct bufferevent* bev = (struct bufferevent*)arg;
read(fd, buf, sizeof(buf));
bufferevent_write(bev, buf, strlen(buf)+1);
} int main(int argc, const char* argv[])
{
struct event_base* base;
base = event_base_new(); struct bufferevent* bev;
bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); // 连接服务器
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(9995);
evutil_inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);
bufferevent_socket_connect(bev, (struct sockaddr*)&serv, sizeof(serv)); // 设置回调
bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL);
bufferevent_enable(bev, EV_READ | EV_PERSIST);
// 创建一个事件
struct event* ev = event_new(base, STDIN_FILENO,
EV_READ|EV_PERSIST, send_cb, bev); event_add(ev, NULL);
event_base_dispatch(base);
event_base_free(base);
return 0;
}

客户端发送数据:

sunminming@sunminming:~/libevent/watermask$ ./client
服务器已连接
a
qwertyuio

服务器接收的数据:

sunminming@sunminming:~/libevent/watermask$ ./server
connect new client from: 127.0.0.1
a
qwertyu

我们从客户端一共发送了两次信息,第一次发送3个字符:'a','\n','\0';第二次发送11个字符'q','w','e','r','t','y','u','i','o','\n','\0')。

因此,读回调函数输出的前10个字符应该为:'a','\n','\0','q','w','e','r','t','y','u';之后还输出了10个buf数组中原本就存在的'\0';最后输出换行符。

libevent笔记5:水位watermarks的更多相关文章

  1. libevent笔记6:ssl bufferevent

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

  2. libevent笔记4:Filter_bufferevent过滤器

    Filter_bufferevent是一种基于bufferevent的过滤器,其本身也是一个bufferevent.能够对底层bufferevent输入缓存区中的数据进行操作(加/解密等)后再读取,同 ...

  3. libevent笔记3:evbuffer

    evbuffer 之前提到bufferevent结构体提供两个缓存区用来为读写提供缓存,并自动进行IO操作.这两个缓存区是使用Libevent中的evbuffer实现的,同样,Libevent中也提供 ...

  4. libevent笔记2:Hello_World

    本篇通过libevent提供的Hello_World demo简单介绍基于libevent的TCP服务器的实现 listener listener是libevent提供的一种监听本地端口的数据结构,在 ...

  5. libevent笔记1:安装及DEMO

    本篇简单记录了libevent的安装过程及基础的先进先出管道Demo,其中demo来自这篇博客,安装过程在这篇博客 实验环境 系统:Ubuntu 18.04.3 libevent版本:libevent ...

  6. libevent库介绍--事件和数据缓冲

    首先在学习libevent库的使用前,我们还要从基本的了解开始,已经熟悉了epoll以及reactor,然后从event_base学习,依次学习事件event.数据缓冲Bufferevent和数据封装 ...

  7. Libevent学习笔记(四) bufferevent 的 concepts and basics

    Bufferevents and evbuffers Every bufferevent has an input buffer and an output buffer. These are of ...

  8. libevent源码阅读笔记(一):libevent对epoll的封装

    title: libevent源码阅读笔记(一):libevent对epoll的封装 最近开始阅读网络库libevent的源码,阅读源码之前,大致看了张亮写的几篇博文(libevent源码深度剖析 h ...

  9. Libevent学习笔记(五) 根据例子学习bufferevent

    libevent中提供了一个Hello-world.c 的例子,从这个例子可以学习libevent是如何使用bufferevent的. 这个例子在Sample中 这个例子之前讲解过,这次主要看下buf ...

随机推荐

  1. window下使用curl操作elasticsearch

    1.下载curlzip,https://curl.haxx.se/download.html; 2.解压,在bin文件夹中找到curl.exe,右键“以管理员身份运行”,cmd e: 换盘符:出现E: ...

  2. C# 调用TRIO控制器ActiveX教程

    最近项目由于用到上位机与TRIO交互,为了使交互编程方便,使用了TRIO的COM组件.记录一下为方便以后自己使用,同时也方便大家做参考! 组件下载地址(百度云盘):https://pan.baidu. ...

  3. Haskell路线

    @ 知乎 @ <I wish i have learned haskell> ———— 包括: Ranks, forall, Monad/CPS,  monadic parser, FFI ...

  4. 用node发布一个包

    手把手教你用npm发布一个包 注:本文引用于简书 http://www.jianshu.com/p/36d3e0e00157   但是内容的话,还是一样的,也就是继续之前的工作,将那个autoRout ...

  5. 【译】使用WebDriver采样器将JMeter与Selenium集成

    原为地址:https://dev.to/raghwendrasonu/jmeter-integration-with-selenium-using-webdriver-sampler-176k 第一步 ...

  6. loadrunner 基本操作

    1.录制(录制选项) 2.回放(运行时设置) 3.添加事物 4.参数化 5.内容检查 6.添加集合点 1.在脚本中添加集合点函数如下: lr_rendezvous("集合点") / ...

  7. JVM参数最佳实践:元空间的初始大小和最大大小

    本文阅读时间大约4分钟. JVM加载类的时候,需要记录类的元数据,这些数据会保存在一个单独的内存区域内,在Java 7里,这个空间被称为永久代(Permgen),在Java 8里,使用元空间(Meta ...

  8. 更改用户host留下的坑

    前言:  我们在创建数据库用户的时候都会指定host,即一个完整的用户可描述为 'username'@'host' .创建用户时不显式指定host则默认为%,%代表所有ip段都可以使用这个用户,我们也 ...

  9. Centos7 samba配置

    目录 免密码只读 加密码可读写 Samba配置了很多次,总是忘,现在写在博客里. 免密码只读 最主要的是免密配置,主要用到了两个配置,要写在[global]里: map to guest = Bad ...

  10. 安装php源码包内的扩展

    本地环境 PHP 7.0.4 (cli) (built: Mar 13 2016 21:50:22) ( NTS ) 安装 进入源码包中的ext文件夹中 [root@test etc]# cd /us ...