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

Code@Pig Home

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

 
 
 

日志

 
 

[libevent] event.h(1) -- I/O event  

2009-04-12 22:44:18|  分类: net_libevent |  标签: |举报 |字号 订阅

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

libevent 是个写 server 挺方便的 lib,可自己经常不记得一些用法(年纪大了?)。无奈,还是好记性不如烂笔头,来一套《基础入门》的总结吧。:-) 今天奉献下 echo server,我是“代码流”,贴代码,不分析,嘿嘿~

记得注意 struct event 的生存周期是要外部管理的,如果写了:
void add_xxx_event() {
    struct event ev;
    ...
    event_add(&ev, NULL);
}
OK,一会你就可以见到 segment fault 了。

闲话休提,下面贴代码:
--------------------------- Main ---------------------------
/* simple echo server */
#include <event.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "mysocket.h"

/* read */
void read_callback(int fd, short events, void *arg)
{
    char buf[1024];
    int n;
    struct event *ev = (struct event *)arg;

    n = read(fd, buf, sizeof(buf));
    if ( n == -1 && errno == EINTR )
    {
        return;
    }
    else if ( n == -1 )
    {
        printf("conn %d error, close it\n", fd);
        event_del(ev);
        free(ev);
        close(fd);
    }
    else if ( n == 0 )
    {
        printf("conn %d close by peer\n", fd);
        event_del(ev);
        free(ev);       
        close(fd);
    }
    else
    {
        write(fd, buf, n);
    }
}

/* listen */
void listen_callback(int listen_fd, short events, void *arg)
{
    int fd = accept(listen_fd, NULL, NULL);
    struct event *ev = malloc(sizeof(struct event));

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

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

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()
{
    event_init();
    add_listen_event();
    event_dispatch();
    return 0;
}


--------------------------- mysocket.h ---------------------------
#ifndef MYSOCKET_H
#define MYSOCKET_H

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <unistd.h>
#include <fcntl.h>

int N_setnonblock(int fd);
int N_new_listen_socket(int port);

#endif


--------------------------- mysocket.c ---------------------------
#include <string.h>
#include "mysocket.h"

int N_setnonblock(int fd)
{
    int flags;

    flags = fcntl(fd, F_GETFL);
    if (flags < 0)
        goto label_nonblock_error;
    flags |= O_NONBLOCK;
    if (fcntl(fd, F_SETFL, flags) < 0)
        goto label_nonblock_error;

    return 0;

label_nonblock_error:
    return -1;
}

int N_new_listen_socket(int port)
{
    int fd;
    struct sockaddr_in in_addr;
    int reuseaddr_on = 1;

    fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( fd < 0 ) return -1;

    // addr reuse
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseaddr_on,
            sizeof(reuseaddr_on)) == -1)
    {
        return -1;
    }

    // bind & listen
    bzero(&in_addr, sizeof(in_addr));
    in_addr.sin_family      = AF_INET;
    in_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    in_addr.sin_port        = htons(port);

    if ( bind(fd, (struct sockaddr *) &in_addr, sizeof(in_addr)) == -1 )
        return -1;

    if ( listen(fd, 5) == -1 )
        return -1;

    // set non-block
    if ( N_setnonblock(fd) == -1 )
        return -1;

    return fd;
}


libevent 2.0 的代码风格,让 event_base 由使用者来维护。
-----------------------------------------------------------
/* simple echo server */
#include <event.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "mysocket.h"

static struct event_base *myevbase;

/* read */
void read_callback(int fd, short events, void *arg)
{
    char buf[1024];
    int n;
    struct event *ev = (struct event *)arg;

    n = read(fd, buf, sizeof(buf));
    if ( n == -1 && errno == EINTR )
    {
        return;
    }
    else if ( n == -1 )
    {
        printf("conn %d error, close it\n", fd);
        event_del(ev);
        event_free(ev);
        close(fd);
    }
    else if ( n == 0 )
    {
        printf("conn %d close by peer\n", fd);
        event_del(ev);
        event_free(ev);
        close(fd);
    }
    else
    {
        write(fd, buf, n);
    }
}

/* listen */
void listen_callback(int listen_fd, short events, void *arg)
{
    int fd = accept(listen_fd, NULL, NULL);
    struct event *ev = malloc(sizeof(*ev));

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

    event_assign(ev, myevbase, fd, EV_READ|EV_PERSIST, read_callback, ev);
    event_add(ev, NULL);
}

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

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

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

/* main */
int main()
{
    myevbase = event_base_new();
    add_listen_event();
    event_base_dispatch(myevbase);
    return 0;
}
-----------------------------------------------------------

--------------------
ps. 网易 blog 没有语法加亮,可惜。blog 速度越来越慢了,可恨。

  评论这张
 
阅读(1176)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

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

页脚

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