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

推荐订阅源

F
Full Disclosure
V
Vulnerabilities – Threatpost
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
SecWiki News
SecWiki News
S
Security @ Cisco Blogs
Schneier on Security
Schneier on Security
B
Blog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园_首页
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
W
WeLiveSecurity
N
News and Events Feed by Topic
F
Fortinet All Blogs
PCI Perspectives
PCI Perspectives
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
腾讯CDC
Last Week in AI
Last Week in AI
月光博客
月光博客
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Help Net Security
Help Net Security
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Heimdal Security Blog
L
LINUX DO - 最新话题
GbyAI
GbyAI
The Hacker News
The Hacker News
罗磊的独立博客
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V2EX - 技术
V2EX - 技术
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
O
OpenAI News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

博客园 - 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;
}