Connection——连接管理有什么

Connection 回答的问题是:「一条连接的生死谁来管?」 它被逼出来的原因是「连接的生命周期散落在 EventLoop 的各个回调里」。这一篇讲它有什么——职责、内部结构、边界、异常、形态,以及它和 Session 的分工。


一、它解决什么问题

连接不是「accept 一下就完了」。一条连接从建立到关闭,有一整套生命周期:

1
2
3
建立   accept 后登记
维护 收发数据、跟踪状态(正常/半关闭/超时)
关闭 正常关闭 / 异常断开,清理资源

在只有 EventLoop 的阶段,这套动作散落在各个回调里:

1
2
3
// on_accept 回调里:创建连接
// on_readable 回调里:收数据 + 判断是否断开
// on_close 回调里:清理连接

连接状态一复杂(半关闭、超时、被重置),每个回调都要重复判断「这个连接现在什么状态」。这就是 Connection 被逼出来的原因——把「一条连接的生死」独立成一个组件。


二、它有什么(内部结构)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Connection {
// —— 数据 ——
int fd_; // 连接的文件描述符
ConnState state_; // 状态:CONNECTING / ESTABLISHED / CLOSING / CLOSED
Session* session_; // 关联的会话(连接上挂一个会话)

public:
// —— 接口 ——
Connection(int fd);
void on_established(); // 连接建立
void on_data(const char* bytes, size_t len); // 收到数据
void on_closed(); // 连接关闭
void close(); // 主动关闭
};
1
2
3
数据:fd + 连接状态 + 关联的 Session
算法:状态机(CONNECTING → ESTABLISHED → CLOSING → CLOSED)
接口:on_established / on_data / on_closed / close

连接的状态机

1
2
3
CONNECTING ──连接成功──→ ESTABLISHED ──正常/异常关闭──→ CLOSED

└──主动 close ──→ CLOSING → CLOSED

三、它的边界:只管「生死」,不管「内容」

1
2
3
✅ 管:一条连接的建立、状态跟踪、关闭、资源清理
❌ 不管:字节是什么意思(那是 Session/解析层的事)
❌ 不管:什么时候有数据(那是 EventLoop 的事)
1
2
3
Connection 收到「fd 3 有数据」
→ 它只把字节交给 Session(或上层)
→ 字节是「命令」还是「数据」,Connection 不关心

Connection 管「一条连接这个实体」的存在,不管「连接里流动的内容」。


四、它和 Session 的分工(容易混)

Connection 和 Session 是两个东西,别混:

1
2
3
4
5
6
Connection:连接的「生命周期」——建立、关闭、清理
Session: 会话的「状态」——缓冲区、协议状态、活跃时间

关系:一个 Connection 上挂一个 Session
连接建立 → 创建 Connection + 挂一个 Session
连接断开 → 销毁 Session + 销毁 Connection
1
2
Connection 管「这条连接还活着吗」
Session 管「这个会话此刻是什么状态」

一个管死活,一个管状态。生命周期是二元的(活/死),状态是连续的(缓冲了多少、握手到哪一步)。


五、它的形态:有状态组件,类封装

1
2
有状态:fd、连接状态、关联的 Session
有生命周期:accept 时创建,断开时销毁

所以用类封装,每个连接一个 Connection 对象:

1
2
3
4
Connection* conn = new Connection(client_fd);
conn->on_established();
// ... 事件驱动 ...
conn->close();

六、它的异常

1
2
3
4
5
6
7
8
9
10
11
ECONNREFUSED(连接被拒绝):
主动连接对方时对方没监听
→ 处理:重试 / 记录日志 / 上报

ECONNRESET(连接被重置):
对方异常断开(RST)
→ 处理:关闭连接、清理资源

超时断开:
长时间没有数据(心跳超时)
→ 处理:主动关闭,通知会话清理

Connection 的异常都是「连接层面」的——它处理「连接怎么没了」,不处理「消息格式错」(解析层)或「业务规则违反」(业务层)。


七、它和其他组件的关系

1
2
3
4
Connection ← 被 EventLoop 驱动(新连接事件 → 创建;断开事件 → 销毁)
Connection → 挂一个 Session(连接建立时创建,断开时销毁)
Connection → 用 Buffer 收发字节
Connection → 引用 Protocol 格式(知道消息长什么样,但不做解析)
1
2
3
EventLoop ──驱动──→ Connection ──挂载──→ Session

└──使用──→ Buffer / Protocol

八、小结

1
2
3
4
5
6
7
8
9
Connection 有什么:
职责:一条连接的生死(建立、状态跟踪、关闭、清理)
结构:fd + 连接状态机 + 关联的 Session
接口:on_established / on_data / on_closed / close
边界:只管「生死」,不管「内容」
形态:有状态组件,类封装,一连接一对象
异常:ECONNREFUSED / ECONNRESET / 超时

一句话:Connection 管「这条连接还活着吗」,Session 管「这个会话是什么状态」。