TcpServer 模块
1️⃣ 概述
在高性能网络框架中,TcpServer 模块往往处于 “承上启下” 的核心地位:
- 向下 封装了底层的
Socket套接字细节, - 向上 为各类 应用层协议 提供基础的连接管理和数据传输能力。
在 sylar 框架中,TcpServer 是一个高层次的封装,旨在提供一个 简单、稳定 且 支持多核并发 的 TCP 服务器基类。TcpServer 深度集成了 协程调度器 (IOManager) 和 套接字封装 (Socket),使得开发者可以专注于业务逻辑,而无需处理复杂的非阻塞 I/O 和多线程竞争。
2️⃣ 设计理念
在 sylar 框架中,TcpServer 不仅仅是一个简单的套接字监听器,它是底层网络组件与复杂业务协议之间的核心桥梁。其架构设计的核心灵魂在于:通过高度解耦实现极致的并发效率与扩展性。

基于 Reactor 模式的双调度器架构
这是 TcpServer 高并发能力的核心。它将网络事件处理划分为两个阶段,并允许通过不同的 IOManager 进行物理隔离:
Accept调度器: 专注于监听(listen)与接收(accept)。只负责捕获新连接,确保即使在高负载下,新用户的接入响应依然迅速。IO调度器: 专注于具体的业务逻辑(Handle)。一旦连接建立,任务会被立即 “派发” 给IO调度器,从而避免了耗时的业务计算阻塞后续连接的接入。
对象生命周期的异步安全
在 协程 与 异步 编程中,最棘手的问题莫过于 “对象在任务执行中途被析构”。
shared_from_this的妙用:TcpServer继承自std::enable_shared_from_this。- 在
start()和startAccept()中,通过传递shared_from_this()给协程调度器,确保了只要还有连接在处理,TcpServer对象就始终存活,彻底杜绝了悬空指针引发的崩溃。
协议无关性与高扩展性
TcpServer 本身并不关心传输的是 HTTP 网页还是 Redis 指令:
- 业务逻辑抽象化: 通过将
handleClient设计为Virtual Function,基类只负责管理连接的接入和Socket的生命周期,而具体的 “协议解析” 和 “响应逻辑” 完全交给子类去实现。
优雅停机
利用 m_isStop 标志位结合 stop() 方法,系统能够有序地关闭所有监听中的 Socket,并取消cancel 调度器上的残留任务,保证了服务在退出时不会产生僵尸连接或资源泄漏。
3️⃣ 启动流程
构造函数
1 | TcpServer::TcpServer(IOManager* ioworker, IOManager* accept) |
m_acceptworke:负责 接收客户连接 的线程调度器。m_ioworker:负责后续 处理客户读写连接handleClient的线程调度器。m_recvtimeout:处理客户端连接超时m_name:服务器的名称m_type:服务器的类型m_isStop:是否处于停止状态
绑定监听阶段 bind
由于服务器可能有多个 ip:port,因此分为 单地址版本 和 多地址版本。
为每个 ip:port 建立 socket,对其进行监听。如果有一个地址 绑定 或 监听 失败,就认为 bind 失败。
1 | bool TcpServer::bind(Address::ptr address) |
启动阶段 start/ startAccept
针对每个 sock,先将其扔进 accpet 任务队列,等待 accept 中的协程执行函数 startAccept 启动对 sock 的监听,如果客户连接,在工作线程 io_worker 中投递任务 handleClient ,等待空闲协程处理对该用户的连接。
1 | bool TcpServer::start() |
1 | void TcpServer::startAccept(Socket::ptr sock) |
执行阶段 handleClient
handleClient 被定义为 virtual 虚函数。因为:
- 基类
TcpServer只负责底层的网络基础设施(如bind、listen、accept)。 - 具体的应用协议(如
HTTP解析、Echo回显等)全部通过在子类中重写handleClient来实现。1
2
3
4void TcpServer::handleClient(Socket::ptr client)
{
SYLAR_LOG_INFO(g_logger) << "handleClient: " << *client;
}
停止阶段 stop
设置停止标志 m_isStop = true,这会让所有 startAccept 循环在下一轮检查时退出。在 accept 线程中投递任务:对所有sock 停止关注,并关闭 sock,以及清理 sock 集合。
1 | void TcpServer::stop() |
