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

推荐订阅源

T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Securelist
K
Kaspersky official blog
V
Vulnerabilities – Threatpost
C
Cisco Blogs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
Forbes - Security
Forbes - Security
Spread Privacy
Spread Privacy
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Palo Alto Networks Blog
H
Hacker News: Front Page
L
Lohrmann on Cybersecurity
Cloudbric
Cloudbric
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
I
InfoQ
人人都是产品经理
人人都是产品经理
PCI Perspectives
PCI Perspectives
月光博客
月光博客
爱范儿
爱范儿
Jina AI
Jina AI
WordPress大学
WordPress大学
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
Google Online Security Blog
Google Online Security Blog
W
WeLiveSecurity
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
博客园 - 司徒正美
Scott Helme
Scott Helme
AI
AI
L
LangChain Blog
A
Arctic Wolf
博客园 - 【当耐特】
量子位
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
腾讯CDC
博客园 - 叶小钗
Last Week in AI
Last Week in AI
S
Secure Thoughts

博客园 - 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服务,支持文件下载 (7)libevent filter(过滤器) (6)libevent定时器
(5)libevent evbuffer
osbreak · 2023-11-09 · via 博客园 - osbreak

数据封装evBuffer

libevent 的 evbuffer 实现了为向后面添加数据和从前面移除数据而优化的字节队列。

1. 创建和释放evbuffer

struct evbuffer *evbuffer_new(void); 		// 分配和返回一个新的空 evbuffer
void evbuffer_free(struct evbuffer *buf);  	// 释放 evbuffer 和其内容。

2. 创建和释放evconnlistener

evconnlistener_new() 函数的 flags 参数传入一些标志

  • LEV_OPT_LEAVE_SOCKETS_BLOCKING 接收新套接字后, 设置为非阻塞的
  • LEV_OPT_CLOSE_ON_FREE 释放连接监听器会关闭底层套接字
  • LEV_OPT_CLOSE_ON_EXEC 连接监听器会为底层套接字设置 close-on-exec 标志
  • LEV_OPT_REUSEABLE 套接字是可重用的
  • LEV_OPT_THREADSAFE 为监听器分配锁
/* 链接监听器回调 */
typedef void (*evconnlistener_cb)(struct evconnlistener *listener,
    evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr);
/* 假定已经将套接字绑定到要监听的端口,然后通过 fd 传入这个套接字 */
struct evconnlistener *evconnlistener_new(struct event_base *base,
	evconnlistener_cb cb, 	// 新连接到达时,监听 器调用你给出的回调函数。
	void *ptr, 		// ptr 指针将传递给回调函数。 
	unsigned flags,		// 参数控制回调函数的行为,下面会更详细论述。 
	int backlog,		// 最大未决连接数。
	evutil_socket_t fd);
    
/* 分配和绑定套接字, 传输要绑定到的地址和地址长度 */
struct evconnlistener *evconnlistener_new_bind(struct event_base *base,
	evconnlistener_cb cb, 	// 新连接到达时,监听 器调用你给出的回调函数。
	void *ptr,		// ptr 指针将传递给回调函数。 
	unsigned flags,	flags 	// 参数控制回调函数的行为,下面会更详细论述。 
	int backlog,		// 最大未决连接数。
	const struct sockaddr *sa, 
	int socklen);
    
void evconnlistener_free(struct evconnlistener *lev);

3.evbuffer与线程安全

  • 默认情况下,在多个线程中同时访问 evbuffer 是不安全的。可以调用 evbuffer_enable_locking() 。如果 lock 参数为 NULL , libevent 会使用evthread_set_lock_creation_callback 提供的锁创建函数创建一个锁 。否则,libevent 将 lock 参数用作锁。
  • evbuffer_lock()和 evbuffer_unlock()函数分别请求和释放 evbuffer 上的锁。可以使用这两个函数让一系列操作是原子的。如果 evbuffer 没有启用锁,这两个函数不做任何操作。
int evbuffer_enable_locking(struct evbuffer *buf, void *lock);
void evbuffer_lock(struct evbuffer *buf);
void evbuffer_unlock(struct evbuffer *buf);

4.启用和禁用 evconnlistener

int evconnlistener_disable(struct evconnlistener *lev);
int evconnlistener_enable(struct evconnlistener *lev);

5.调整 evconnlistener 的回调函数

void evconnlistener_set_cb(struct evconnlistener *lev, evconnlistener_cb cb, void *arg);

6.检查evbuffer

/* 这个函数返回 evbuffer 存储的字节数 */
size_t evbuffer_get_length(const struct evbuffer *buf);

7.检查evbuffer

/* 返回连续地存储在 evbuffer前面的字节数(evbuffer中的数据可能存储在多个分隔开的内存块中) */
size_t evbuffer_get_contiguous_space(const struct evbuffer *buf);

8.检测 evconnlistener

/*返回监听器关联的套接字*/
evutil_socket_t evconnlistener_get_fd(struct evconnlistener *lev);
/*返回event_base*/
struct event_base *evconnlistener_get_base(struct evconnlistener *lev);

9. 向evbuffer添加数据

/* 这个函数添加 data 处的 datalen 字节到 buf 的末尾,成功时返回0,失败时返回-1*/
int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen);


/* 这些函数添加格式化的数据到 buf 末尾 */
int evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)
// evbuffer_add(buf, "Hello world 2.0.1", 17);

/* 格式参数和其他参数的处理分别与 C 库函数 printf 和 vprintf 相同。函数返回添加的字节数 */
int evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap);
// evbuffer_add_printf(buf, "Hello %s %d.%d.%d", "world", 2, 0, 1);

/* 这个函数修改缓冲区的最后一块,或者添加一个新的块,使得缓冲区足以容纳 datlen 字节, 而不需要更多的内存分配。*/
int evbuffer_expand(struct evbuffer *buf, size_t datlen);

10. evbuffer数据移动

/*  src 中的所有数据移动到 dst 末尾,成功时返回0,失败时返回-1 */
int evbuffer_add_buffer(struct evbuffer *dst, struct evbuffer *src);

/* 从 src 中移动 datlen 长度字节到 dst 末尾,如果字节数小于 datlen,所有字节被移动。函数返回移动的字节数 */
int evbuffer_remove_buffer(struct evbuffer *src, 
                    struct evbuffer *dst,
                    size_t datlen);

11. 侦测错误

typedef void (*evconnlistener_errorcb)(struct evconnlistener *lis, void *ptr);

/*监听器设置了错误回调函数,则监听器发生错误 时回调函数就会被调用*/
void evconnlistener_set_error_cb(struct evconnlistener *lev,
    evconnlistener_errorcb errorcb);