libevent笔记5:水位watermarks
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的更多相关文章
- libevent笔记6:ssl bufferevent
Libevent另外提供了基于openssl的bufferevent来支持ssl,通过特殊的ssl bufferevent来对数据进行加密. ps:本文不对openssl相应的接口做介绍因为不熟 SS ...
- libevent笔记4:Filter_bufferevent过滤器
Filter_bufferevent是一种基于bufferevent的过滤器,其本身也是一个bufferevent.能够对底层bufferevent输入缓存区中的数据进行操作(加/解密等)后再读取,同 ...
- libevent笔记3:evbuffer
evbuffer 之前提到bufferevent结构体提供两个缓存区用来为读写提供缓存,并自动进行IO操作.这两个缓存区是使用Libevent中的evbuffer实现的,同样,Libevent中也提供 ...
- libevent笔记2:Hello_World
本篇通过libevent提供的Hello_World demo简单介绍基于libevent的TCP服务器的实现 listener listener是libevent提供的一种监听本地端口的数据结构,在 ...
- libevent笔记1:安装及DEMO
本篇简单记录了libevent的安装过程及基础的先进先出管道Demo,其中demo来自这篇博客,安装过程在这篇博客 实验环境 系统:Ubuntu 18.04.3 libevent版本:libevent ...
- libevent库介绍--事件和数据缓冲
首先在学习libevent库的使用前,我们还要从基本的了解开始,已经熟悉了epoll以及reactor,然后从event_base学习,依次学习事件event.数据缓冲Bufferevent和数据封装 ...
- Libevent学习笔记(四) bufferevent 的 concepts and basics
Bufferevents and evbuffers Every bufferevent has an input buffer and an output buffer. These are of ...
- libevent源码阅读笔记(一):libevent对epoll的封装
title: libevent源码阅读笔记(一):libevent对epoll的封装 最近开始阅读网络库libevent的源码,阅读源码之前,大致看了张亮写的几篇博文(libevent源码深度剖析 h ...
- Libevent学习笔记(五) 根据例子学习bufferevent
libevent中提供了一个Hello-world.c 的例子,从这个例子可以学习libevent是如何使用bufferevent的. 这个例子在Sample中 这个例子之前讲解过,这次主要看下buf ...
随机推荐
- 上下文的哲学思考:上下文=环境 & 上下文=对象+行为+环境
事物的存在和运行所依赖的全部资源(能够看到和使用的一切)(环境). 上下文研究的是一个时段内,多个主体.对象在历次操作活动时,在空间的信息投射. 上下文是事物存在和生存活动的气泡,气泡消失,事物消失. ...
- dotnet验证参数
组长提了一个需求,前端传递过来参数的时候,我们要验证一下参数是否都传递过来了,所以我专门写了一个验证工具类,调用就好了. 第一个参数为 前端传递到Controller封装的实体类,第二个参数为这个实体 ...
- c# asp.net core取当月第一天和最后一天及删除最后一个字符的多种方法
当月第一天0时0分0秒 DateTime.Now.AddDays( - DateTime.Now.Day).Date 当月最后一天23时59分59秒 DateTime.Now.AddDays( - D ...
- 我是如何一步步编码完成万仓网ERP系统的(五)产品库设计 1.产品类别
https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...
- vue 利用路由跨页传参
第一页,点击进入第二页进行传值: <template> <div id="app"> <div><router-link to=" ...
- android studio学习----通过github的URL怎么导入新的工程
这一切的前提是你装了git,有了github帐号,之后就很简单,但是导入之后交给android studio 也会发生各种编译错误,这个时候就需要自己去一一解决了,主要还是 引用依赖版本的问题 第一 ...
- Centos7配置ssh免密登录群发
ssh免密登录是客户端发送自己的公钥到服务器.用公钥进行解密,自己生成的私钥进行加密. 首先在客户端查看sshd服务是否启动 [zhiwei@zhiwei1 ~]$ ps -Af|grep sshd; ...
- 让istio中的jaeger跑起来
现在的水平,仅止于让它跑起来.:) 同样的环境,microk8s+istio. 步骤如下: 一,使用kubectl get pod -n istio-system查看所有istio的POD运行正常. ...
- Linux下使用cx_Oracle的一些配置
在安装完成cx_Oracle后,import cx_Oracle时报错,首先查看.bash_profile文件中环境变量配置 # .bash_profile # Get the aliases an ...
- JMeter【第五篇】关联:5种方法
前几天在Q群里看到群友发的最近10年性能测试工具使用率的统计,最近的2018年,jmeter+loadrunner占了93%的使用率,说明这两个是主流,其中,jmeter的使用率逐年提升,现在已经超过 ...