`
wbj0110
  • 浏览: 1602843 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

libevent入门教程:Echo Server based on libevent

阅读更多

ent_set_timeouts(bev, struct timeval *READ, struct timeval *WRITE)来设置读写超时, 在error_cb里面处理超时。
    *. read_cb和write_cb的原型是
        void read_or_write_callback(struct bufferevent *bev, void *arg)
      error_cb的原型是
        void error_cb(struct bufferevent *bev, short error, void *arg) //这个是event的标准回调函数原型
      可以从bev中用libevent的API提取出event_base、sockfd、input/output等相关数据,详情RTFM~
    

    于是代码简化到只需要几行的read_cb和error_cb函数即可:

void read_cb(struct bufferevent *bev, void *arg) {
    char line[256];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);
    while (n = bufferevent_read(bev, line, 256), n > 0)
        bufferevent_write(bev, line, n);
}

void error_cb(struct bufferevent *bev, short event, void *arg) {
    bufferevent_free(bev);
}



    于是一个支持大并发量的echo server就成型了!下面附上无注释的echo server源码,110行,多抄几遍,就能完全弄懂啦!更复杂的例子参见官方文档里面的【Example: A simpler ROT13 server with Libevent】

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>

#include <event2/event.h>
#include <event2/bufferevent.h>

#define LISTEN_PORT 9999
#define LISTEN_BACKLOG 32

void do_accept(evutil_socket_t listener, short event, void *arg);
void read_cb(struct bufferevent *bev, void *arg);
void error_cb(struct bufferevent *bev, short event, void *arg);
void write_cb(struct bufferevent *bev, void *arg);

int main(int argc, char *argv[])
{
    int ret;
    evutil_socket_t listener;
    listener = socket(AF_INET, SOCK_STREAM, 0);
    assert(listener > 0);
    evutil_make_listen_socket_reuseable(listener);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(LISTEN_PORT);

    if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        perror("bind");
        return 1;
    }

    if (listen(listener, LISTEN_BACKLOG) < 0) {
        perror("listen");
        return 1;
    }

    printf ("Listening...\n");

    evutil_make_socket_nonblocking(listener);

    struct event_base *base = event_base_new();
    assert(base != NULL);
    struct event *listen_event;
    listen_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base);
    event_add(listen_event, NULL);
    event_base_dispatch(base);

    printf("The End.");
    return 0;
}

void do_accept(evutil_socket_t listener, short event, void *arg)
{
    struct event_base *base = (struct event_base *)arg;
    evutil_socket_t fd;
    struct sockaddr_in sin;
    socklen_t slen;
    fd = accept(listener, (struct sockaddr *)&sin, &slen);
    if (fd < 0) {
        perror("accept");
        return;
    }
    if (fd > FD_SETSIZE) {
        perror("fd > FD_SETSIZE\n");
        return;
    }

    printf("ACCEPT: fd = %u\n", fd);

    struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bev, read_cb, NULL, error_cb, arg);
    bufferevent_enable(bev, EV_READ|EV_WRITE|EV_PERSIST);
}

void read_cb(struct bufferevent *bev, void *arg)
{
#define MAX_LINE    256
    char line[MAX_LINE+1];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);

    while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
        line[n] = '\0';
        printf("fd=%u, read line: %s\n", fd, line);

        bufferevent_write(bev, line, n);
    }
}

void write_cb(struct bufferevent *bev, void *arg) {}

void error_cb(struct bufferevent *bev, short event, void *arg)
{
    evutil_socket_t fd = bufferevent_getfd(bev);
    printf("fd = %u, ", fd);
    if (event & BEV_EVENT_TIMEOUT) {
        printf("Timed out\n"); //if bufferevent_set_timeouts() called
    }
    else if (event & BEV_EVENT_EOF) {
        printf("connection closed\n");
    }
    else if (event & BEV_EVENT_ERROR) {
        printf("some other error\n");
    }
    bufferevent_free(bev);
}
分享到:
评论

相关推荐

    libevent echo server

    libevent example. echo server. use c++11 gcc 4.8.5 thread_pool singleton , io thread , servant thread layer

    libevent实现UDP relay服务器与客户端

    在项目中,`libevent-client`和`libevent-server`分别代表了客户端和服务器的源代码文件,包含了上述过程的实现细节。通过阅读和分析这些代码,可以更深入地理解libevent在UDP relay场景中的应用。

    学习libevent入门电子书

    《学习libevent入门电子书》是一本针对libevent这一开源事件库的学习资料,它对于深入理解和使用libevent具有极大的价值。libevent是一个高度可移植的库,它为编写高性能、异步网络应用提供了基础。在现代软件开发,...

    libevent 教程

    使用 libevent 可以快速构建一个 Echo Server。首先,创建一个 event_base,用于管理和调度事件。然后,创建一个监听事件,并将其绑定到 event_base 上。当有连接请求时,回调函数会被触发,处理请求并返回响应。 7...

    libevent入门学习资料

    附件为本人整理的libevent的入门学习资料,时候零基础学习。

    基于libevent的tcp server开发环境的完整工程

    在提供的工程文件中,`tcp_server.sln`是Visual Studio的解决方案文件,`tcp_server.v11.suo`是用户设置文件,`Debug`目录包含编译后的可执行文件和中间文件,`libevent`目录可能包含了libevent库的头文件和库文件。...

    libevent库, http-server静态文件服务器示例

    cd sample mkdir htdocs vim htdocs/index.html ./http-server -p 18080 -v htdocs curl -i http://127.0.0.1:18080/index.html

    libevent_webservice:基于libevent的简单异步多线程Webservice

    "libevent_webservice:基于libevent的简单异步多线程Webservice" 这个标题提到了两个关键概念:libevent和异步多线程Webservice。Libevent是一个开源库,用于处理事件通知,尤其适用于编写高性能、可扩展的网络...

    evpp based echo server

    "evpp based echo server" 是一个基于qihoo360公司开源的网络框架EVPP构建的简单回显服务器。EVPP(Efficient Vector Protocol Processor)是一个高性能、异步事件驱动的C++网络库,设计用于开发高并发、低延迟的...

    libevent demo

    在"libevent demo"中,我们通常会看到一个基础的echoserver示例,它是使用libevent来实现的。Echoserver是一个简单的服务器,它接收客户端发送的数据并原样返回,常用于测试网络连接和数据传输。 **Libevent核心...

    Multi-Threaded Libevent Server Example

    Multithreaded, libevent-based socket server. http://sourceforge.net/p/libevent-thread/code/ci/master/tree/README

    libevent多线程client、server

    libevent,多线程,client,serverlibevent多线程, 参考mariotcp 参考http://blog.csdn.net/i_am_jojo/article/details/7587838流程图

    libevent-devel-1.4.13-1.x86_64.rpm

    Name : libevent-devel Version : 1.4.13 Vendor : StartCom Ltd_, http://www_startcom_org Release : 1 Date : 2010-04-07 22:14:06 Group : Development/Libraries Source RPM : libevent-1.4.13-1.src.rpm ...

    openwrt-libevent21:用于 openwrt 的 libevent 2.1 包

    openwrt-libevent21 用于 openwrt 的 libevent 2.1 包为目标平台快速构建包: 从获取相应的预构建 OpenWrt SDK(例如针对 ar71xx 平台的) 交叉编译- 需要将工具链二进制文件添加到PATH环境变量并定义STAGING_DIR 。...

    libevent-comment:libevent-1.4.15源码阅读注释

    《libevent-1.4.15源码阅读注释》是针对libevent库的一个详细解析,这个开源项目为系统编程提供了强大的事件通知机制。libevent是一个轻量级的库,它允许程序员以统一的方式处理各种事件,如网络连接、定时器以及...

    【最新】C++ 使用libEvent实现http的post, get功能

    libEvent是一个跨平台的事件通知库,它允许程序员编写高性能的异步网络服务。本篇将深入探讨如何利用libEvent库在C++中实现HTTP的POST和GET请求。 首先,理解HTTP的基本概念至关重要。HTTP(超文本传输协议)是...

    libevent多线程处理

    本文将深入探讨如何在多线程环境中使用Libevent进行事件处理,并分享一个基于Libevent的多线程实现案例。 首先,理解Libevent的核心机制至关重要。Libevent提供了一个事件基础结构,它能够将来自不同来源的事件(如...

    libevent服务器和客户端

    **libevent服务器与客户端详解** libevent是一个高度可移植、高性能的事件通知库,它能够帮助程序员编写出高效的网络服务程序。在这个项目中,我们实现了一个基于libevent的简单服务器和客户端,它们能够互相发送...

    iOS_libevent

    **iOS_libevent** libevent是一个开源的事件通知库,它为C语言编程提供了一种机制,可以在多个事件源上等待事件的发生。这个库特别适用于网络编程,如HTTP服务器、TCP和UDP服务器,以及处理定时任务。在iOS开发中,...

Global site tag (gtag.js) - Google Analytics