Libevent源码分析-----连接监听器evconnlistener

本文详细分析了Libevent中的evconnlistener,包括其使用、初始化服务器socket、处理客户端连接请求的流程,以及如何释放evconnlistener。通过evconnlistener,Libevent简化了服务器端的socket、bind、listen、accept等步骤,提供了便利的回调函数来处理新客户端连接。文章还介绍了相关结构体、标志选项和错误处理函数,展示了Libevent在连接监听上的封装策略。
摘要由CSDN通过智能技术生成

        转载请注明出处:http://blog.csdn.net/luotuo44/article/details/38800363



使用evconnlistener:

        基于event和event_base已经可以写一个CS模型了。但是对于服务器端来说,仍然需要用户自行调用socket、bind、listen、accept等步骤。这个过程有点繁琐,为此在2.0.2-alpha版本的Libevent推出了一些对应的封装函数。

        用户只需初始化struct sockaddr_in结构体变量,然后把它作为参数传给函数evconnlistener_new_bind即可。该函数会完成上面说到的那4个过程。下面的代码是一个使用例子。

#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>

#include<stdio.h>
#include<string.h>

#include<event.h>
#include<listener.h>
#include<bufferevent.h>
#include<thread.h>


void listener_cb(evconnlistener *listener, evutil_socket_t fd,
                 struct sockaddr *sock, int socklen, void *arg);

void socket_read_cb(bufferevent *bev, void *arg);
void socket_error_cb(bufferevent *bev, short events, void *arg);

int main()
{
    evthread_use_pthreads();//enable threads

    struct sockaddr_in sin;
    memset(&sin, 0, sizeof(struct sockaddr_in));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(8989);

    event_base *base = event_base_new();
    evconnlistener *listener
            = evconnlistener_new_bind(base, listener_cb, base,
                                      LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE | LEV_OPT_THREADSAFE,
                                      10, (struct sockaddr*)&sin,
                                      sizeof(struct sockaddr_in));

    event_base_dispatch(base);

	 evconnlistener_free(listener);
    event_base_free(base);

    return 0;
}


//有新的客户端连接到服务器
//当此函数被调用时,libevent已经帮我们accept了这个客户端。该客户端的
//文件描述符为fd
void listener_cb(evconnlistener *listener, evutil_socket_t fd,
                 struct sockaddr *sock, int socklen, void *arg)
{
    event_base *base = (event_base*)arg;

	//下面代码是为这个fd创建一个bufferevent
    bufferevent *bev =  bufferevent_socket_new(base, fd,
                                               BEV_OPT_CLOSE_ON_FREE);

    bufferevent_setcb(bev, socket_read_cb, NULL, socket_error_cb, NULL);
    bufferevent_enable(bev, EV_READ | EV_PERSIST);
}


void socket_read_cb(bufferevent *bev, void *arg)
{
    char msg[4096];

    size_t len = bufferevent_read(bev, msg, sizeof(msg)-1 );

    msg[len] = '\0';
    printf("server read the data %s\n", msg);

    char reply[] = "I has read your data";
    bufferevent_write(bev, reply, strlen(reply) );
}


void socket_error_cb(bufferevent *bev, short events, void *arg)
{
    if (events & BEV_EVENT_EOF)
        printf("connection closed\n");
    else if (events & BEV_EVENT_ERROR)
     
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值