栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

libevent库的使用方法实例

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

libevent库的使用方法实例

接写一个很简单的 Time Server 来当作例子:当你连上去以后 Server 端直接提供时间,然后结束连线。event_init() 表示初始化 libevent 所使用到的变数。event_set(&ev, s, EV_READ | EV_PERSIST, connection_accept, &ev) 把 s 这个 File Description 放入 ev (第一个参数与第二个参数),并且告知当事件 (第三个参数的 EV_READ) 发生时要呼叫 connection_accept() (第四个参数),呼叫时要把 ev 当作参数丢进去 (第五个参数)。其中的 EV_PERSIST 表示当呼叫进去的时候不要把这个 event 拿掉 (继续保留在 Event Queue 里面),这点可以跟 connection_accept() 内在注册 connection_time() 的代码做比较。而 event_add(&ev, NULL) 就是把 ev 注册到 event queue 里面,第二个参数指定的是 Timeout 时间,设定成 NULL 表示忽略这项设定。
注:这段代码来自于网络,虽然很粗糙,但是对libevent的使用方法已经说明的很清楚了.
附源码:
复制代码 代码如下:
#include   
#include   
#include   
#include   
#include   
#include   

void connection_time(int fd, short event, struct event *arg)  
{  
    char buf[32];  
    struct tm t;  
    time_t now;  

    time(&now);  
    localtime_r(&now, &t);  
    asctime_r(&t, buf);  

    write(fd, buf, strlen(buf));  
    shutdown(fd, SHUT_RDWR);  

    free(arg);  
}  

void connection_accept(int fd, short event, void *arg)  
{  
   
    fprintf(stderr, "%s(): fd = %d, event = %d.n", __func__, fd, event);  

   
    struct sockaddr_in s_in;  
    socklen_t len = sizeof(s_in);  
    int ns = accept(fd, (struct sockaddr *) &s_in, &len);  
    if (ns < 0) {  
        perror("accept");  
        return;  
    }  

   
    struct event *ev = malloc(sizeof(struct event));  
    event_set(ev, ns, EV_WRITE, (void *) connection_time, ev);  
    event_add(ev, NULL);  
}  

int main(void)  
{  
   
    int s = socket(PF_INET, SOCK_STREAM, 0);  
    if (s < 0) {  
        perror("socket");  
        exit(1);  
    }  

   
    struct sockaddr_in s_in;  
    bzero(&s_in, sizeof(s_in));  
    s_in.sin_family = AF_INET;  
    s_in.sin_port = htons(7000);  
    s_in.sin_addr.s_addr = INADDR_ANY;  
    if (bind(s, (struct sockaddr *) &s_in, sizeof(s_in)) < 0) {  
        perror("bind");  
        exit(1);  
    }  

   
    if (listen(s, 5) < 0) {  
        perror("listen");  
        exit(1);  
    }  

   
    event_init();  

   
    struct event ev;  
    event_set(&ev, s, EV_READ | EV_PERSIST, connection_accept, &ev);  

   
    event_add(&ev, NULL);  

    event_dispatch();  

    return 0;  
}

在写 Nonblocking Network Program 通常要处理 Buffering 的问题,但并不好写,主要是因为 read() 或 recv() 不保证可以一次读到一行的份量进来。
在 libevent 里面提供相当不错的 Buffer Library 可以用,完整的说明在 man event 的时候可以看到,最常用的应该就是以 evbuffer_add()、evbuffer_readline() 这两个 Function,其他的知道存在就可以了,需要的时候再去看详细的用法。
下面直接提供 libevent-buff.c 当作范例,编译后看执行结果,再回头来看 source code 应该就有感觉了:
复制代码 代码如下:
#include   
#include   
#include   

void printbuf(struct evbuffer *evbuf)  
{  
    for (;;) {  
        char *buf = evbuffer_readline(evbuf);  
        printf("* buf = %p, the string = "e[1;33m%se[m"n", buf, buf);  
        if (buf == NULL)  
            break;  
        free(buf);  
    }  
}  

int main(void)  
{  
    struct evbuffer *evbuf;  

    evbuf = evbuffer_new();  
    if (evbuf == NULL) {  
        fprintf(stderr, "%s(): evbuffer_new() failed.n", __func__);  
        exit(1);  
    }  

   
    u_char *buf1 = "gslin";  
    printf("* Add "e[1;33m%se[m".n", buf1);  
    evbuffer_add(evbuf, buf1, strlen(buf1));  
    printbuf(evbuf);  

    u_char *buf2 = " is reading.nAnd he is at home.nLast.";  
    printf("* Add "e[1;33m%se[m".n", buf2);  
    evbuffer_add(evbuf, buf2, strlen(buf2));  
    printbuf(evbuf);  

    evbuffer_free(evbuf);  
}  

最后的 event_dispatch() 表示进入 event loop,当 Queue 里面的任何一个 File Description 发生事件的时候就会进入 callback function 执行。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/65946.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号