使用libevent2 实现 http_server

使用libevent2 实现 http_server

使用http实现libevent

linux http server 完整代码如下:

//LIBS += -levent  qt工程pro 链接设置
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <event.h>
#include <evhttp.h>

void httpserver_handler(struct evhttp_request *req, void *arg)
{
    const char *cmd_type;
    struct evbuffer *buf = evbuffer_new();
    if (buf == NULL)
    {
        printf("evbuffer_new error !\n");
        return;
    }

    switch (evhttp_request_get_command(req))
    {
        case EVHTTP_REQ_GET:    cmd_type = "GET";    break;
        case EVHTTP_REQ_POST:   cmd_type = "POST";   break;
        case EVHTTP_REQ_HEAD:   cmd_type = "HEAD";   break;
        case EVHTTP_REQ_PUT:    cmd_type = "PUT";    break;
        case EVHTTP_REQ_DELETE: cmd_type = "DELETE"; break;
        case EVHTTP_REQ_OPTIONS:cmd_type = "OPTIONS";break;
        case EVHTTP_REQ_TRACE:  cmd_type = "TRACE";  break;
        case EVHTTP_REQ_CONNECT:cmd_type = "CONNECT";break;
        case EVHTTP_REQ_PATCH:  cmd_type = "PATCH";  break;
        default: cmd_type = "unknown"; break;
    }

    printf("%s url=%s \n", cmd_type, evhttp_request_get_uri(req));

    evbuffer_add_printf(buf,"<html>\n"
            "<head>\n"
            "  <title>libevent http server </title>\n"
            "</head>\n"
            "<body>\n"
            "  <h1>libevent http server start success</h1>\n"
            "</body>\n"
            "</html>\n");
    evhttp_send_reply(req, 200, "OK", buf);
}

int create_listener(int port, int backlog)
{
    int ret;
    int fd;
    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        printf("socket error !\n");
        return -1;
    }

    int opt = 1;
    ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);

    ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0)
    {
        printf("bind error !\n");
        return -1;
    }
    ret = listen(fd, backlog);
    if (ret < 0)
    {
        printf("listen error !\n");
        return -1;
    }

    int flags;
    if ((flags = fcntl(fd, F_GETFL, 0)) < 0
        || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
    {
        printf("fcntl error !\n");
        return -1;
    }
    return fd;
}

int start_httpserver(int port)
{
    int ret;
    int fd = create_listener(port, 128);
    if (fd < 0)
    {
        return -1;
        printf("create_listener error !\n");
    }
    struct event_base *base = event_init();
    if (base == NULL)
    {
        printf("event_init error !\n");
        return -1;
    }
    struct evhttp *httpd = evhttp_new(base);
    if (httpd == NULL)
    {
        printf("enhttp_new error !\n");
        return -1;
    }
    ret = evhttp_accept_socket(httpd, fd);
    if (ret != 0)
    {
        printf("evhttp_accept_socket error \n");
        return -1;
    }
    evhttp_set_gencb(httpd, httpserver_handler, NULL);
    printf("http server success started\n");
    event_base_dispatch(base);
    return 0;
}

int main(void)
{
    start_httpserver(8080);
    return 0;
}

基础环境:ubuntu:18.04

编译前安装依赖 :(我们使用libevent 库作为使用的http与网络开源库)

 sudo apt-get install -y  libevent-dev 

编译命令:

g++ main.cpp  -levent -o http_server

http_server 即是编译成功的http server了

运行: 

./http_server

编译与运行示例图:

 

测试:

1、浏览器测试:  浏览器打开:http://127.0.0.1:8080  回车

效果: 

2、通过curl命令命令行测试:  curl http://127.0.0.1:8080    回车

curl 是一个http 客户端命令行软件,非常好用

没有的话需要安装:  sudo apt-get install -y  curl 

 

 

 

部分代码说明: 

如何实现一个http server 
一个高性能网络开源库libevent

memcached 内存数据库的底层网络库是 libevent 

O_NONBLOCK 把监听的socket 设置成了非阻塞的socket 

为甚libevent 是事件驱动的呢
我们写代码的是往里面去注册事件 跟事件的处理回调函数
事件+回调函数  (libevent运行机制!!!!事件驱动)
event_init 初始化libevent

struct evhttp *httpd = evhttp_new(base);
新建一个 libevent 的事件

evhttp_accept_socket(httpd, fd)
把事件跟我们的监听socket 绑定

httpserver_handler 监听socket 的 回调函数 
evhttp_set_gencb(httpd, httpserver_handler, NULL);

event_base_dispatch 是libevent的内部循环函数!!!

通过注册的回调函数 来执行我的代码 

evhttp_request_get_uri 读取客户端的url

evhttp_send_reply 函数是把请求发回给客户端

这个代码一共三个函数

create_listener  就是创建监听socket 
start_httpserver  初始化libevent  ,以及注册了监听socket 的事件处理事件
httpserver_handler 监听socket 的 回调函数 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值