libevent简单的http实现

1 #include <sys/types.h>

2 #include <sys/time.h>

3 #include <sys/queue.h>

4 #include <stdlib.h>

5 #include <err.h>

6 #include <event.h>

7 #include <evhttp.h>

8

9 void generic_handler(struct evhttp_request *req, void *arg)

10 {

11 struct evbuffer *buf;

12 buf = evbuffer_new();

13

14 if (buf == NULL)

15 err(1, "failed to create response buffer");

16

17 evbuffer_add_printf(buf, "Requested: %s", evhttp_request_uri(req));

18 evhttp_send_reply(req, HTTP_OK, "OK", buf);

19

20 evbuffer_free(buf);

21 }

22

23 int main(int argc, char **argv)

24 {

25 struct evhttp *httpd;

26 event_init();

27 httpd = evhttp_start("0.0.0.0", 8080);

28

29 /* Set a callback for requests to "/specific". */

30 /* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */

31

32 /* Set a callback for all other requests. */

33 evhttp_set_gencb(httpd, generic_handler, NULL);

34

35 event_dispatch();

36

37 /* Not reached in this code as it is now. */

38 evhttp_free(httpd);

39 return 0;

40 }


gcc s_http.c -levent
### 使用 libevent 实现 HTTP 功能 libevent 是一个高性能事件驱动网络库,支持多种协议和功能扩展。通过其内置的 `evhttp` 模块,可以轻松实现 HTTP 服务器或客户端。 #### HTTP 服务器实现 以下是基于 libeventHTTP 服务器基本实现方法: 1. **初始化 event_base** 需要先创建一个 `struct event_base*` 对象作为事件循环的核心[^1]。 2. **设置 evhttp** 调用 `evhttp_new()` 创建一个新的 HTTP 服务对象,并将其绑定到指定地址和端口上。 3. **注册回调函数** 使用 `evhttp_set_cb()` 或 `evhttp_set_gencb()` 注册处理请求的回调函数。这些回调会在接收到特定路径的请求时被调用。 4. **启动事件循环** 调用 `event_base_dispatch()` 启动事件循环以监听并响应来自客户端的 HTTP 请求。 下面是简单HTTP 服务器代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <event2/event.h> #include <event2/http.h> void request_handler(struct evhttp_request *req, void *arg) { const char *response_body = "Hello from the server!"; struct evbuffer *buf = evbuffer_new(); evbuffer_add_printf(buf, "%s", response_body); evhttp_send_reply(req, HTTP_OK, "OK", buf); // 发送回复给客户端 evbuffer_free(buf); } int main(int argc, char **argv) { struct event_base *base; struct evhttp *http; base = event_base_new(); // 初始化 event_base http = evhttp_new(base); if (!http || !base) { fprintf(stderr, "Error initializing libevent\n"); return 1; } int port = 8080; // 设置监听端口 if (evhttp_bind_socket(http, "0.0.0.0", port)) { // 绑定 IP 和端口 fprintf(stderr, "Could not bind to port %d\n", port); return 1; } evhttp_set_gencb(http, request_handler, NULL); // 设置通用回调函数 printf("Starting server on port %d...\n", port); event_base_dispatch(base); // 开始事件循环 evhttp_free(http); event_base_free(base); return 0; } ``` --- #### HTTP 客户端实现 对于 HTTP 客户端的功能,则可以通过 `evhttp_connection` 来完成请求发送与接收操作。 1. **建立连接** 利用 `evhttp_connection_base_new()` 函数来构建新的 HTTP 连接实例[^2]。 2. **发起请求** 可以使用 `evhttp_make_request()` 方法向目标 URL 提交 GET/POST 等类型的请求。 3. **解析返回的数据包** 当远程主机回应之后,在自定义的回调里读取相应的内容体以及状态码等信息。 下面是一个基础版的 HTTP 客户端例子: ```c #include <stdio.h> #include <stdlib.h> #include <event2/event.h> #include <event2/http.h> #include <event2/buffer.h> void on_http_complete(struct evhttp_request *req, void *ctx) { if (req == NULL) { puts("Request failed."); return; } enum evhttp_command_type type = EVHTTP_REQ_GET; int status_code = evhttp_request_get_response_code(req); printf("Response code: %d (%s)\n", status_code, evhttp_request_get_response_code_line(req)); struct evbuffer *buff = evhttp_request_get_input_buffer(req); size_t len = evbuffer_get_length(buff); char *data = malloc(len + 1); evbuffer_copyout(buff, data, len); data[len] = '\0'; printf("Received body:\n%s\n", data); free(data); } int main(void){ struct event_base *base = event_base_new(); struct evhttp_connection *conn = evhttp_connection_base_new(base, NULL, "www.example.com", 80); struct evhttp_request *request = evhttp_request_new(on_http_complete, NULL); evhttp_add_header(request->output_headers,"Host","www.example.com"); evhttp_make_request(conn,request,EVHTTP_REQ_GET,"/"); event_base_dispatch(base); evhttp_connection_free(conn); event_base_free(base); return EXIT_SUCCESS; } ``` --- #### 编译说明 为了成功编译上述程序,请确保安装了 libevent 库及其开发头文件。可采用如下命令进行编译(假设已配置好环境变量 `$LIBEVENT`): ```bash gcc -o http_server http_server.c -I$LIBEVENT/include -levent ``` 或者如果项目较大建议编写 Makefile 文件简化过程如引用中的描述那样。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值