• 正文
  • 相关推荐
申请入驻 产业图谱

C++ 高并发网络通信框架设计 基于 epoll 的多客户端事件驱动模型实战

07/08 09:22
1428
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

一、项目目标与核心功能

功能 描述
支持多客户端并发连接 每秒支持上千连接不崩溃
采用非阻塞 IO 模型 无阻塞读写,资源复用高
事件驱动架构(基于 epoll) 支持输入/输出/关闭等事件
简洁线程模型(主线程事件循环) 避免线程爆炸,后续可拓展线程池支持
模块化结构易扩展 支持路由、业务回调、连接生命周期钩子等

二、网络模型选择:epoll 为什么适合高并发?

模型 描述
select 最早期,fd 数有限制(1024),性能线性下降
poll 数量支持多,但仍需遍历,性能不高
epoll 事件驱动,支持边缘触发,支持百万连接

本文将使用 epoll 的边缘触发(EPOLLET)模型,结合非阻塞 IO 达到高性能。

三、项目结构概览

text
NetServer
├── epoll_loop.cpp ← epoll 主循环
├── connection.cpp ← 客户端连接封装
├── server.cpp ← 启动监听
├── handler.cpp ← 用户业务逻辑回调
└── main.cpp ← 程序入口

四、核心组件:连接结构封装

cpp
class Connection {
public:
int fd;
std::string ip;
std::string buffer;
Connection(int fd, const std::string& ip) : fd(fd), ip(ip) {}

void onRead();
void onWrite();
void onClose();
};

五、非阻塞 IO 设置工具函数

cpp
void setNonBlocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

六、epoll 初始化与事件循环

cpp
int epoll_fd = epoll_create1(0);
const int MAX_EVENTS = 1024;
epoll_event events[MAX_EVENTS];
while (true) {
int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; ++i) {
int fd = events[i].data.fd;
if (fd == listen_fd) {
acceptNewConnection();
} else if (events[i].events & EPOLLIN) {
connectionMap[fd]->onRead();
} else if (events[i].events & (EPOLLHUP | EPOLLERR)) {
connectionMap[fd]->onClose();
}
}
}

七、监听 socket 初始化

cpp
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
setNonBlocking(listen_fd);
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = INADDR_ANY;

bind(listen_fd, (sockaddr*)&addr, sizeof(addr));
listen(listen_fd, SOMAXCONN);

epoll_event ev{};
ev.data.fd = listen_fd;
ev.events = EPOLLIN;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev);

八、接受新连接

cpp
void acceptNewConnection() {
while (true) {
sockaddr_in client_addr{};
socklen_t len = sizeof(client_addr);
int client_fd = accept(listen_fd, (sockaddr*)&client_addr, &len);
if (client_fd < 0) break;
setNonBlocking(client_fd);

std::string ip = inet_ntoa(client_addr.sin_addr);
auto conn = std::make_shared<Connection>(client_fd, ip);
connectionMap[client_fd] = conn;

epoll_event ev{};
ev.data.fd = client_fd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);

std::cout << "新连接来自: " << ip << "n";
}
}

九、Connection::onRead 实现

cpp
void Connection::onRead() {
char buf[4096];
while (true) {
ssize_t n = read(fd, buf, sizeof(buf));
if (n > 0) {
buffer.append(buf, n);
} else if (n == 0) {
onClose();
break;
} else {
if (errno == EAGAIN || errno == EWOULDBLOCK) break;
onClose();
break;
}
}
if (!buffer.empty()) {
std::cout << "收到: " << buffer << "n";
write(fd, buffer.c_str(), buffer.size());
buffer.clear();
}
}

十、Connection::onClose 实现

cpp
void Connection::onClose() {
close(fd);
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
connectionMap.erase(fd);
std::cout << "连接断开: " << ip << "n";
}

十一、连接生命周期与事件回调可注入(接口化)

cpp
class IHandler {
public:
virtual void onMessage(Connection& conn, const std::string& data) = 0;
virtual void onConnect(Connection& conn) = 0;
virtual void onClose(Connection& conn) = 0;
};
void registerHandler(std::shared_ptr<IHandler> h);

十二、测试逻辑处理器实现(Echo)

cpp
class EchoHandler : public IHandler {
public:
void onConnect(Connection& conn) override {
std::cout << "[连接建立] " << conn.ip << "n";
}
void onMessage(Connection& conn, const std::string& data) override {
std::cout << "[收到数据] " << data << "n";
write(conn.fd, data.c_str(), data.size());
}

void onClose(Connection& conn) override {
std::cout << "[连接断开] " << conn.ip << "n";
}
};

十三、支持协议路由与拆包机制(拓展)

  • 按行协议拆包(n 分隔)

  • 固定包头长度 + 包体长度识别

  • JSON / Protobuf / 自定义协议

  • 注册不同协议处理器

十四、性能与稳定性增强建议

能力 实现方式
多线程调度 每核一个 epoll + 线程池处理数据
连接限流 最大连接数判断 + 拒绝策略
消息缓存池 避免频繁 new/delete
写事件注册优化 可写时注册 EPOLLOUT 处理大数据输出
异常保护 所有 read/write 操作判断错误码处理

十五、实际应用场景

系统类型 网络模块作用
即时通信系统 支持长连接,消息推送、会话管理
网关服务 连接前端与后端服务,协议中转
嵌入式中控 与设备保持连接,实现指令交互
游戏服务端 玩家状态同步、命令处理、心跳管理

十六、总结

本篇搭建了一个结构清晰、可扩展的 C++ 高并发通信框架,具备:

  • 基于 epoll 的事件驱动架构

  • 非阻塞 IO,支持上千连接并发处理

  • 模块化连接结构与事件处理机制

  • 易扩展的协议解析与业务注入能力

该框架可作为大型项目的网络基础架构,也可用于嵌入式通信控制层,具有强工程实用价值。

相关推荐