惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
博客园 - 叶小钗
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Stack Overflow Blog
Stack Overflow Blog
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 聂微东
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
N
Netflix TechBlog - Medium
B
Blog
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理

博客园 - osbreak

ros2::tf2 QML::qml与c++数据交互 k8s:: Service 管理 deployment postgresql 索引 postgresql 基本类型 postgresql 基础运维 PLSQL 触发器 PLSQL 程序包 PLSQL 执行块 PLSQL 基础数据类型 PLSQL oracle安装部署 mysql事务与隔离 mysql慢查询分析 mysql建增删改查 mysql常用总结 (9)libevent 常用设置 (8)libevent 构建libevent http服务,支持文件下载 (6)libevent定时器 (5)libevent evbuffer
(7)libevent filter(过滤器)
osbreak · 2023-11-11 · via 博客园 - osbreak

可以通过添加filter对输入或输出数据进行转换和过滤,可以在读取前和写入后对数据进行一系列的预处理操作。

/**
* 事件过滤回调
*/
bufferevent_filter_result filter_in(evbuffer *s, evbuffer *d, ev_ssize_t limit, 
		bufferevent_flush_mode mode, void *arg )
{
	cout << "2、filter_in\n" << endl;
	char data[1024] = { 0 };
	
	// 读取并清理原数据
	int len = evbuffer_remove(s, data, sizeof(data) - 1);

	// 所有字母转成大写
	for (int i = 0; i < len; ++i)
	{
		data[i] = toupper(data[i]);
	}

	evbuffer_add(d, data, len);
	return BEV_OK;
}

bufferevent_filter_result filter_out(evbuffer *s, evbuffer *d, ev_ssize_t limit, 
		bufferevent_flush_mode mode, void *arg )
{
	cout << "4、filter_out\n" << endl;
	char data[1024] = { 0 };
	// 读取并清理原数据
	int len = evbuffer_remove(s, data, sizeof(data) - 1);

	string str = "";
	str += "================\n";
	str += data;
	str += "================\n";

	evbuffer_add(d, str.c_str(), str.size());
	return BEV_OK;
}

void read_cb(bufferevent*bev, void *arg)
{
	cout << "3、read_cb\n" << endl;
	char data[1024] = { 0 };
	int len = bufferevent_read(bev, data, sizeof(data) - 1);
	cout << data << endl;

	//回复客户消息,经过输出过滤
	bufferevent_write(bev, data, len);

}
void write_cb(bufferevent*bev, void *arg)
{
	cout << "5、write_cb\n" << endl;
}

void event_cb(bufferevent*bev, short events, void *arg)
{
	cout << "6、event_cb\n" << endl;
}
void listen_cb(struct evconnlistener * e, evutil_socket_t s, struct sockaddr *a, int socklen, void *arg)
{
	event_base *base = (event_base*)arg;
	cout << "1、listen_cb\n" << endl;
	// 创建bufferevent 
	bufferevent *bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE);
	// 绑定bufferevent filter
	bufferevent *bev_filter = bufferevent_filter_new(bev,
		filter_in,			//输入过滤函数
		filter_out,			//输出过滤函数
		BEV_OPT_CLOSE_ON_FREE,		//关闭filter是同时关闭bufferevent
		0,				//清理的回调函数
		0				//传递给回调的参数
	);

	//设置bufferevent的回调 
	bufferevent_setcb(bev_filter, read_cb, write_cb, event_cb, NULL);//回调函数的参数

	bufferevent_enable(bev_filter, EV_READ | EV_WRITE); // 设置读写权限
}

int main()
{
#ifdef _WIN32 
	//初始化socket库
	WSADATA wsa;
	WSAStartup(MAKEWORD(2, 2), &wsa);
#else
	// 忽略管道信号,发送数据给已关闭的socket
	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
		return 1;
#endif

	// 创建libevent的上下文
	event_base * base = event_base_new();

	// 监听端口
	// socket ,bind,listen 绑定事件
	sockaddr_in sin;
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SPORT);

	evconnlistener *ev = evconnlistener_new_bind(base,	// libevent的上下文
		listen_cb,					// 接收到连接的回调函数
		base,						// 回调函数获取的参数 arg
		LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,	// 地址重用,evconnlistener关闭同时关闭socket
		10,						// 连接队列大小,对应listen函数
		(sockaddr*)&sin,				// 绑定的地址和端口
		sizeof(sin)
	);
	// 事件分发处理
	if (base)
		event_base_dispatch(base);
	if (ev)
		evconnlistener_free(ev);
	if (base)
		event_base_free(base);
#ifdef _WIN32
	WSACleanup();
#endif
	return 0;
}