面试题答案
一键面试- 创建基本事件监听机制:
- 引入Libevent头文件:
#include <event2/event.h>
- 初始化Libevent库:
event_base* base = event_base_new(); if (!base) { // 处理初始化失败 return 1; }
- 创建一个用于监听的文件描述符(例如监听TCP连接的socket):
int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { // 处理socket创建失败 event_base_free(base); return 1; } struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(12345); sin.sin_addr.s_addr = INADDR_ANY; if (bind(listen_fd, (struct sockaddr*)&sin, sizeof(sin)) == -1) { // 处理bind失败 close(listen_fd); event_base_free(base); return 1; } if (listen(listen_fd, 10) == -1) { // 处理listen失败 close(listen_fd); event_base_free(base); return 1; }
- 创建一个事件来监听该文件描述符:
struct event* listen_event = event_new(base, listen_fd, EV_READ | EV_PERSIST, nullptr, nullptr); if (!listen_event) { // 处理事件创建失败 close(listen_fd); event_base_free(base); return 1; }
- 注册处理连接事件的回调函数:
- 定义回调函数:
static void accept_connection_cb(evutil_socket_t fd, short what, void* arg) { // 处理新连接,例如accept新的socket int client_fd = accept(fd, nullptr, nullptr); if (client_fd != -1) { // 对新连接的socket进行处理,如设置非阻塞等 evutil_make_socket_nonblocking(client_fd); // 可以在这里创建新的事件来处理这个client_fd的后续读写事件 } }
- 使用定义好的回调函数重新创建事件:
struct event* listen_event = event_new(base, listen_fd, EV_READ | EV_PERSIST, accept_connection_cb, nullptr); if (!listen_event) { // 处理事件创建失败 close(listen_fd); event_base_free(base); return 1; }
- 添加事件到事件循环:
if (event_add(listen_event, nullptr) == -1) { // 处理添加事件失败 event_free(listen_event); close(listen_fd); event_base_free(base); return 1; }
- 启动事件循环:
event_base_dispatch(base);
- 最后,记得释放资源:
event_free(listen_event); close(listen_fd); event_base_free(base);