Back to VNotes

C++ WebServer / 08

Keep-Alive:长连接如何复用

v3.1 加入 persistent connection,后续 HTTP 解析中继续完善 Connection 字段。Keep-Alive 让一个 TCP 连接处理多个请求。

这一阶段要解决什么问题

短连接每个请求都要建立和关闭 TCP 连接,成本较高。Keep-Alive 允许同一个连接继续等待下一个 HTTP 请求。

原来的实现有什么缺陷

一个请求处理完就 close,逻辑简单,但压测时建连和断连成本明显,也不符合 HTTP/1.1 默认长连接的行为。

我是怎么改的

解析请求头时读取 Connection 字段,设置 keep_alive。响应发送完成后,如果 keep_alive 为 true,就重置当前请求状态并重新注册 EPOLLIN;否则关闭连接。

核心代码 / 关键逻辑

if (header["Connection"] == "keep-alive") {
    conn.keep_alive = true;
}

if (write_done && conn.keep_alive) {
    conn.reset_state();
    mod_epoll(fd, EPOLLIN | EPOLLET | EPOLLONESHOT);
} else if (write_done) {
    close_connection(fd);
}

踩坑记录

长连接复用的难点是“清理本次请求状态,但保留 fd”。如果 read_buffer、write_buffer、解析状态或文件映射没有复位干净,下一次请求会被旧状态污染。