注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[libevent] event.h(4) ---- bufferevent  

2010-02-01 09:01:44|  分类: net_libevent |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
libevent-1.4.12-stable, libevent-2.0.4-alpha

对于 stream-oriented 的数据形式,无论是 tcp 还是 file data,我们都会为其建立一个 buffer,当数据到达时,从 fd 中将数据读入 buffer,再进行使用。
这样的情景很通用,所以 libevent 也专门封装了一下。

event.h / evbuffer.c,虽然源文件名字叫 evbuffer,但函数名都是 bufferevent_XXX,- -# 真是不统一。(貌似2.x开始,改了)
buffer event 为 read/write 事件都内建了一个 buf,进而再把 error handler 行为从 read/write 行为中分开,最后再支持一下 low/high watermark。

low/high watermark 有啥用呢?
对于 read event, low watermark 决定了 buf 中有多少数据后,才会回调 read_callback。比如,假设我们的协议格式为 cmd(byte) + len(short) + content(len * byte),则我们可以设置 low watermark = byte + short,这样,收到 read_callback,我们肯定知道 cmd/len 已经到位。
对于 read event,一旦 buf 数据超过 high watermark,则停止对应 fd 的 read event 的监听,知道上层应用消化掉这些 buf 为止。

对于 write event,要说明一下,调用 bufferevent_write 发送的数据,都会被发送成功,bufferevent_new 中注册的 write_callback,会在 buf 内容小于 low watermark 时回调。默认 low watermark 就是 0,相当于数据发送完成时通知外部。
high watermark 对 write event 来说是无意义的。

下面看看 echo server 的例子
-----------------------------------------------
#include <event.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mysocket.h"

struct event_base *base;

/* read callback */
void read_callback(struct bufferevent *bufev, void *arg)
{
    char buf[80];
    size_t n;
    n = bufferevent_read(bufev, buf, sizeof(buf)-1);
    buf[n] = '\0';
    printf("recv: %s", buf);

    bufferevent_write(bufev, buf, n);
}

void error_callback(struct bufferevent *bufev, short what, void *arg)
{
    int fd;

    if (what & (EVBUFFER_ERROR|EVBUFFER_EOF))
    {
        fd = (int)arg;
        printf("err or eof, fd = %d\n", fd);
        close(fd);
        bufferevent_free(bufev);
    }
}

/* listen */
void listen_callback(int listen_fd, short events, void *arg)
{
    int fd = accept(listen_fd, NULL, NULL);
    struct bufferevent *bufev;

    printf("fd %d conn...\n", fd);

    bufev = bufferevent_new(fd, read_callback,
        NULL, error_callback, (void *)fd);
    bufferevent_enable(bufev, EV_READ);
}

void add_listen_event()
{
    struct event *ev = malloc(sizeof(struct event));
    int fd;

    fd = N_new_listen_socket(6666);
    printf("listen fd = %d\n", fd);

    event_set(ev, fd, EV_READ|EV_PERSIST, listen_callback, ev);
    event_add(ev, NULL);
}

/* main */
int main()
{
    base = event_init();
    add_listen_event();
    event_dispatch();
    return 0;
}
-----------------------------------------------
$ ./a.out
listen fd = 4
fd 6 conn...
recv: hello
recv: foo
err or eof, fd = 6
-----------------------------------------------

  评论这张
 
阅读(2549)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017