Libevent 不仅仅是一个网络 IO 库,它还附带了一个轻量级的
HTTP 协议实现——evhttp。虽然它不如 Nginx
强大,但用于嵌入式设备、内部 API
服务或简单的文件服务器已经绰绰有余。
1. 快速上手
编写一个返回 “Hello World” 的 HTTP 服务器非常简单。
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
// 请求处理回调
void generic_handler(struct evhttp_request *req, void *arg) {
// 1. 创建响应 buffer
struct evbuffer *buf = evbuffer_new();
if (!buf) return;
evbuffer_add_printf(buf, "Hello World! Requested: %s\n", evhttp_request_get_uri(req));
// 2. 发送响应 (HTTP 200 OK)
evhttp_send_reply(req, HTTP_OK, "OK", buf);
// 3. 清理
evbuffer_free(buf);
}
int main() {
struct event_base *base = event_base_new();
struct evhttp *http = evhttp_new(base);
// 绑定端口
if (evhttp_bind_socket(http, "0.0.0.0", 8080) != 0) {
fprintf(stderr, "Bind failed\n");
return 1;
}
// 设置通用回调 (处理所有未匹配特定 URI 的请求)
evhttp_set_gencb(http, generic_handler, NULL);
event_base_dispatch(base);
evhttp_free(http);
event_base_free(base);
return 0;
}2. 核心功能
2.1. 路由分发
除了
evhttp_set_gencb,你还可以为特定路径设置回调:
evhttp_set_cb(http, "/images", image_handler, NULL);
evhttp_set_cb(http, "/api/login", login_handler, NULL);2.2. 解析参数
evhttp 提供了简单的 URI 解析功能:
const char *uri = evhttp_request_get_uri(req);
struct evhttp_uri *decoded = evhttp_uri_parse(uri);
const char *query = evhttp_uri_get_query(decoded);
// ... 解析 query string ...2.3. 处理 POST Body
struct evbuffer *in_buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(in_buf);
// 读取数据...3. 局限性
虽然 evhttp
很好用,但在生产环境中使用需注意:1. 仅支持
HTTP/1.1: 不支持 HTTP/2 或 HTTP/3。 2.
单线程: 默认情况下,evhttp
依附于创建它的
event_base。如果需要多线程处理,需要自己创建多个
event_base 和 evhttp 实例,并利用
SO_REUSEPORT 绑定同一端口。 3.
功能缺失: 没有原生的 WebSocket
支持,没有完善的 Keep-Alive
超时管理(需要自己加定时器)。
完整代码: 02-http-server.c
4. 总结
evhttp 是 Libevent
赠送的一个实用工具。对于不需要复杂 Web 特性的 C/C++
后端服务,它是最快的实现路径。但如果你的需求涉及
HTTP/2、WebSocket 或极高的并发,建议集成
nghttp2 或使用专业的 Web 服务器。
上一篇: 04-architecture/business-integration.md - 业务集成模式 下一篇: 05-protocols/evdns.md - 异步 DNS 解析
源码下载
本文相关源码已整理,共 1 个文件。
文章导航
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Libevent 深度剖析与实战指南】现代 Web 协议集成
Libevent 原生不支持 HTTP/2 和 QUIC,但这并不妨碍我们集成 nghttp2 和 ngtcp2。本文探讨如何基于 Libevent 构建下一代 Web 服务。
【Libevent 深度剖析与实战指南】异步 DNS 解析 (evdns)
告别阻塞的 getaddrinfo,使用 Libevent 内置的 evdns 实现高性能异步域名解析。
【Libevent 深度剖析与实战指南】UDP 通信编程
如何在 Libevent 中处理 UDP 通信。为什么 Bufferevent 不适合 UDP?使用原始 Event 接口实现高性能 UDP 服务。
【Libevent 深度剖析与实战指南】多构建工具链集成 (Build Systems)
告别手写 gcc 命令,详解如何在 Makefile、CMake 和 Bazel 项目中优雅地集成 Libevent。