4. Not Selected 状态详解:初始状态特征、监听与连接请求处理、超时与重试机制

Not Selected 状态是 HSMS 连接状态机中的初始状态,也是所有 TCP 连接建立后的第一个稳定状态。在该状态下,通信双方尚未完成 Select (S) 或 Select with Data (S6F1/S6F2) 等会话建立流程,因此不能进行任何 SECS-II 消息的交换。本章将深入分析 Not Selected 状态的核心特征、监听与连接请求处理逻辑,以及 T3 超时在该状态下的特殊行为与恢复策略。

关键概念: Not Selected 状态是 HSMS 连接的生命周期起点,也是状态机中最“脆弱”的阶段——任何 T3 超时或连接异常都会导致状态回退或连接断开。

4.1 初始状态特征

当 TCP 连接成功建立后,HSMS 实体自动进入 Not Selected 状态。该状态具有以下特征:

  • 无会话上下文: 设备 ID、控制块 ID、消息序列号等会话参数均未初始化。
  • 仅允许控制消息: 只能发送和接收 HSMS 控制消息(如 Select.req、Select.rsp、Linktest.req、Linktest.rsp),禁止任何 SECS-II 数据消息。
  • T3 超时激活: 当发送 Select.req 后,T3 定时器启动,等待 Select.rsp 响应。
  • 连接可被关闭: 任何一方可在 Not Selected 状态下主动发起 Disconnect.req 关闭连接。
属性 Not Selected 状态值 说明
会话 ID 未分配 设备 ID 尚未协商
允许消息类型 仅控制消息 Select.req/rsp, Linktest.req/rsp, Disconnect.req/rsp
T3 定时器 激活(发送 Select.req 后) 默认 45 秒,可配置
连接保持 TCP 连接保持打开 等待 Select 流程完成
状态转换目标 Selected 或 Disconnected 成功则进入 Selected,失败则断开
工程提示: 在 Not Selected 状态下,如果收到非控制消息(如 SECS-II 数据消息),接收方应直接丢弃并记录错误日志,不应触发任何状态转换。

4.2 监听与连接请求处理

在 Not Selected 状态下,HSMS 实体需要同时处理两种角色:主动连接方(Active) 和 被动监听方(Passive)。两种角色的行为差异主要体现在 Select 流程的发起时机上。

4.2.1 主动连接方(Active)

主动方在 TCP 连接建立后,立即发送 Select.req 控制消息,并启动 T3 定时器。Select.req 消息包含以下关键字段:

Message Header:
  Session ID: 0xFFFF (未选择)
  Stream: 0x00
  Function: 0x01 (Select.req)
  PType: 0x00 (控制消息)
  SType: 0x01 (Select)
  System Bytes: 0x00000001 (递增序列号)

主动方在发送 Select.req 后,进入 等待 Select.rsp 的子状态。在此期间,主动方可以接收 Linktest.req 并回复 Linktest.rsp,但不会处理其他控制消息。

4.2.2 被动监听方(Passive)

被动方在 TCP 连接建立后,不会主动发送任何消息,而是等待接收 Select.req。当收到 Select.req 后,被动方执行以下步骤:

  1. 验证 Select.req 的格式和系统字节是否合法。
  2. 检查设备 ID 是否已被其他连接占用(如果设备 ID 在 Select.req 中指定)。
  3. 分配会话资源,生成会话上下文。
  4. 发送 Select.rsp,其中包含响应代码(0x0000 表示成功)。
  5. 状态转换至 Selected。
注意: 被动方在 Not Selected 状态下收到 Select.req 后,如果资源分配失败(如设备 ID 冲突),应发送 Select.rsp 并携带错误代码(如 0x0001),然后保持在 Not Selected 状态,等待主动方重试或断开。

4.2.3 监听与连接请求处理流程图

Not Selected 状态监听与连接请求处理流程 Not Selected 状态:监听与连接请求处理流程 TCP 连接建立 Not Selected 状态 角色判断 主动方:发送 Select.req 启动 T3 定时器 等待 Select.rsp 被动方:等待 Select.req 收到 Select.req 发送 Select.rsp Selected 状态

4.3 超时与重试机制

在 Not Selected 状态下,T3 超时是最关键的异常场景。T3 定时器在发送 Select.req 后启动,如果在规定时间内未收到 Select.rsp,则触发超时处理流程。

4.3.1 T3 超时触发条件

  • 主动方: 发送 Select.req 后,T3 定时器到期未收到 Select.rsp。
  • 被动方: 被动方不启动 T3 定时器,但如果在 Not Selected 状态下长时间未收到任何消息,可启动连接保活机制(如 Linktest)。

4.3.2 超时恢复策略

当 T3 超时发生时,HSMS 实体应执行以下恢复步骤:

  1. 重试 Select.req: 重新发送 Select.req,并重置 T3 定时器。重试次数通常为 3 次(可配置)。
  2. 递增系统字节: 每次重试时,系统字节应递增,以便接收方区分重试消息。
  3. 连接断开: 如果重试次数耗尽仍未收到响应,则发送 Disconnect.req 并关闭 TCP 连接。
  4. 日志记录: 记录超时事件、重试次数和最终结果,用于故障诊断。
重试次数 行为 T3 超时时间 后续动作
第 1 次 重新发送 Select.req 45 秒(默认) 重置 T3 定时器
第 2 次 重新发送 Select.req 45 秒 重置 T3 定时器
第 3 次 重新发送 Select.req 45 秒 若仍超时,断开连接
超过 3 次 发送 Disconnect.req N/A 关闭 TCP 连接,进入 Disconnected 状态
最佳实践: 建议将 T3 超时重试次数配置为 3 次,超时时间根据网络延迟调整(通常 30-60 秒)。在重试间隔中,可以插入短暂的延迟(如 1-2 秒),避免网络风暴。

4.3.3 超时恢复状态机

Not Selected 状态 T3 超时恢复状态机 T3 超时恢复状态机 发送 Select.req 等待 Select.rsp 收到响应? 收到 Select.rsp 进入 Selected 状态 T3 超时 重试次数 < 3? 是:重发 Select.req 断开连接

4.4 异常场景与处理建议

常见异常: 在 Not Selected 状态下,如果收到重复的 Select.req(系统字节相同),应忽略并保持当前状态,避免重复分配资源。
  • 网络分区: 如果 T3 超时后重试仍失败,可能是网络分区导致。建议在重试 3 次后断开连接,并等待上层应用重新建立 TCP 连接。
  • 设备 ID 冲突: 被动方在 Not Selected 状态下收到 Select.req 时,如果设备 ID 已被占用,应返回错误代码并保持在 Not Selected 状态,等待主动方重试。
  • 半开连接: 如果 TCP 连接处于半开状态(一方已关闭,另一方未感知),Not Selected 状态下的 Select.req 将永远无法收到响应,最终触发 T3 超时并断开连接。
调试建议: 在开发阶段,建议在 Not Selected 状态下打印所有接收到的消息头,包括系统字节和 SType,以便快速定位 Select 流程中的问题。