libevent-1.4.12-stable, libevent-2.0.4-alpha
evbuffer 应在 bufferevent 之前介绍,因为 bufferevent 是依赖 evbuffer 作为底层实现的。
而悲剧的是,evbuffer_xxx 的实现在 buffer.c 中,而 bufferevent_xxx 则在 evbuffer.c。名字不统一啊。
struct evbuffer 中几个 field 的含义:misalign, 已经被 read 掉的数据长度,但出于高效,并不随时把 yyy 部分覆盖 xxx 部分。
off, 未被 read 的数据长度
total, 分配的 buf 的总长度
buffer, 指向 yyy 的开始
origin_buffer, 指向 xxx 的开始
cb, cbarg, 用于实现 buf 长度改变时的回调
|-- misalign ---|--- off ---|
|xxxxxxxxxxxxxxx|yyyyyyyyyyy|--------------------|
| ------------------ total --------------------|
(浏览器无法对齐,请贴到 notepad 中)
常用函数:evbuffer_add, 往 buf 中放数据
evbuffer_remove, 从 buf 中读取数据
evbuffer_drain, 丢弃 buf 中 n 个数据
evbuffer_readline, 从 buf 中读出“以 \r, \n, \r\n, \n\r 结尾”的一行,返回的 char * 需要外部负责释放
evbuffer_read, 从 fd 读数据到 buf 中
evbuffer_write, 将 buf 的数据写到 fd 中
照例,最后上代码:
----------------------------------------------------
#include <event.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h> // open
#include <unistd.h> // close
void buf_change_cb(struct evbuffer *eb,
size_t old, size_t new, void *arg)
{
printf("old_len:%u, new_len:%u\n", old, new);
}
int main()
{
struct evbuffer *eb;
char lines[] = "line1\r\nline2\rline3\nline4\n\rnothing";
char *on
e_line;
char buf[80];
size_t n;
u_char *p;
int fd;
eb = evbuffer_new();
// readline
evbuffer_add(eb, lines, sizeof(lines)-1);
while (1)
{
one_line = evbuffer_readline(eb);
if ( one_line == NULL )
break;
printf("line: %s\n", one_line);
free(one_line);
}
// drain & remove
evbuffer_drain(eb, 2);
n = evbuffer_remove(eb, buf, sizeof(buf)-1);
buf[n] = '\0';
printf("got: %s\n", buf);
// printf & find
evbuffer_add_printf(eb, "%d = %s", 10, "hello");
p = evbuffer_find(eb, (u_char *)"hel", 3);
printf("find(\"hel\") = %s\n", (p ? "found" : "not found"));
// fd read / write
fd = open("./test", O_CREAT|O_WRONLY|O_TRUNC, 0644);
evbuffer_write(eb, fd);
close(fd);
fd = open("./test", O_RDONLY);
evbuffer_read(eb, fd, -1);
close(fd);
n = evbuffer_remove(eb, buf, sizeof(buf)-1);
buf[n] = '\0';
printf("read file: %s\n", buf);
// buf change callback
evbuffer_setcb(eb, buf_change_cb, NULL);
evbuffer_add(eb, "abc", 3);
evbuffer_remove(eb, buf, 2);
return 0;
}
----------------------------------------------------
$ ./a.out
line: line1
line: line2
line: line3
line: line4
got: thing
find("hel") = found
read file: 10 = hello
old_len:0, new_len:3
old_len:3, new_len:1
----------------------------------------------------
评论