3. HSMS 协议详解:TCP/IP 传输层、连接建立与关闭、会话管理、消息格式、超时机制 (T3-T8)
HSMS(High-Speed SECS Message Services)是 SECS/GEM 协议族中基于 TCP/IP 的传输层协议。它将 SECS-II 消息封装为 HSMS 消息,通过可靠的 TCP 连接在主机与设备之间传输。本章深入解析 HSMS 的传输层特性、连接生命周期、会话管理、消息帧格式以及关键的 T3-T8 超时机制。
3.1 HSMS 协议栈与 TCP/IP 传输层
HSMS 直接运行在 TCP 之上,利用 TCP 的可靠传输、流量控制和拥塞控制机制,为上层 SECS-II 提供无差错、有序的字节流服务。与 RS-232 的 SECS-I 不同,HSMS 支持高速、长距离通信。
核心特性: HSMS 使用 TCP 端口号 5000(默认)或 5001(加密),采用主动/被动连接模式,支持多会话复用同一 TCP 连接。
3.2 连接建立与关闭
HSMS 定义了两种连接模式:主动(Active)和被动(Passive)。主动方发起 TCP 连接请求,被动方监听端口。连接建立后,双方通过 HSMS 控制消息完成会话初始化。
3.2.1 连接建立流程
- TCP 三次握手:主动方(通常是主机)向被动方(设备)发起 TCP 连接。
- 发送 Select.req:主动方发送 HSMS 控制消息,请求建立会话。
- 响应 Select.rsp:被动方回复 Select.rsp,携带通信能力协商结果。
- 连接就绪:双方进入通信状态,可以交换 SECS-II 数据消息。
测试要点:验证 Select.req 中的 Device ID 和通信能力字段是否与设备配置一致。不一致时,设备应返回 Select.rsp 且状态码为“拒绝”。
3.2.2 连接关闭方式
| 关闭方式 | 触发条件 | 行为描述 |
|---|---|---|
| 正常关闭 | 应用层调用断开 | 发送 Separate.req,对方回复 Separate.rsp,然后 TCP 四次挥手 |
| 超时关闭 | T6/T7/T8 超时 | 直接发送 TCP RST 或 FIN,不等待应用层确认 |
| 异常关闭 | TCP 连接中断 | 底层检测到连接断开,通知上层会话失效 |
3.3 会话管理
HSMS 会话(Session)是建立在 TCP 连接之上的逻辑通信通道。一个 TCP 连接可以承载多个会话,但实际应用中通常为一对一关系。会话通过 Device ID 唯一标识。
3.3.1 会话状态机
HSMS 会话状态机定义了 5 个状态:
- NOT SELECTED:TCP 已连接,但未建立 HSMS 会话。
- SELECTED:会话已建立,可以交换数据消息。
- NOT CONNECTED:TCP 连接已断开。
- SELECTING:正在发送 Select.req,等待响应。
- WAITING:等待对方重新建立会话。
3.4 消息格式
HSMS 消息由 消息头(Header)和消息体(Body)组成。消息头固定 10 字节,消息体为可选的 SECS-II 数据。
3.4.1 消息头结构
| 字节偏移 | 字段 | 长度 | 描述 |
|---|---|---|---|
| 0 | Length | 4 字节 | 消息总长度(包含头+体),大端序 |
| 4 | Device ID | 2 字节 | 设备标识,bit15 为消息方向位 |
| 6 | Stream/Function | 2 字节 | 高字节 Stream,低字节 Function |
| 8 | P/B Type | 1 字节 | bit7: P-bit, bit6: W-bit, bit5-0: 消息类型 |
| 9 | System Bytes | 1 字节 | 系统字节(高 8 位),与后续 3 字节组成 4 字节 System ID |
常见错误:Device ID 的 bit15 必须正确设置。bit15=0 表示消息从主机发往设备,bit15=1 表示从设备发往主机。错误的方向位会导致消息被丢弃。
3.4.2 消息类型
HSMS 定义了 7 种控制消息和 1 种数据消息:
| 消息类型 | 代码 | 方向 | 用途 |
|---|---|---|---|
| Data Message | 0 | 双向 | 传输 SECS-II 数据 |
| Select.req | 1 | 主动→被动 | 请求建立会话 |
| Select.rsp | 2 | 被动→主动 | 响应会话请求 |
| Deselect.req | 3 | 双向 | 请求释放会话 |
| Deselect.rsp | 4 | 双向 | 响应释放请求 |
| Separate.req | 9 | 双向 | 通知对方即将断开连接 |
| Linktest.req | 5 | 双向 | 测试连接是否存活 |
| Linktest.rsp | 6 | 双向 | 响应连接测试 |
3.5 超时机制 (T3-T8)
HSMS 定义了 6 个关键超时参数,用于保障通信的可靠性和异常处理。这些超时是 HSMS 一致性测试的核心验证点。
| 超时 | 名称 | 默认值 | 触发条件 | 超时后行为 |
|---|---|---|---|---|
| T3 | Reply Timeout | 45 s | 发送需要回复的消息后等待响应 | 重传或上报错误 |
| T4 | Select Timeout | 10 s | 发送 Select.req 后等待 Select.rsp | 重试或断开连接 |
| T5 | Connect Timeout | 10 s | 主动方发起 TCP 连接后等待完成 | 连接失败,重试 |
| T6 | Separate Timeout | 5 s | 发送 Separate.req 后等待 Separate.rsp | 直接关闭 TCP 连接 |
| T7 | Linktest Timeout | 60 s | 发送 Linktest.req 后等待 Linktest.rsp | 断开连接 |
| T8 | Inter-Character Timeout | 5 s | TCP 字节流中相邻字节到达间隔 | 丢弃不完整消息 |
测试策略:超时测试是 HSMS 一致性测试的难点。建议使用以下方法:
1. 构造延迟响应,验证 T3/T4/T7 超时后的重传或断开行为。
2. 模拟 TCP 连接中断,验证 T5 超时后的重连机制。
3. 发送不完整消息,验证 T8 超时后的消息丢弃行为。
1. 构造延迟响应,验证 T3/T4/T7 超时后的重传或断开行为。
2. 模拟 TCP 连接中断,验证 T5 超时后的重连机制。
3. 发送不完整消息,验证 T8 超时后的消息丢弃行为。
3.6 一致性测试要点总结
针对 HSMS 协议的一致性测试,需要覆盖以下关键场景:
- 连接建立:验证 TCP 三次握手、Select.req/rsp 交互、Device ID 和通信能力协商。
- 消息格式:验证消息头各字段的正确性,包括 Length、Device ID、S/F、P/B Type、System Bytes。
- 会话管理:验证状态机转换的正确性,包括 SELECTED、NOT SELECTED、NOT CONNECTED 等状态。
- 超时处理:验证 T3-T8 超时后的行为,包括重传、断开、重连等。
- 异常场景:验证非法消息、重复 Select、未授权断开等异常处理。
推荐工具:使用 Wireshark 抓包分析 HSMS 消息,配合自定义测试脚本模拟异常场景。对于自动化测试,建议使用 Python 的
socket 库直接构造 HSMS 消息帧。
# Python 示例:构造 HSMS Select.req 消息
import struct
import socket
def build_select_req(device_id=0, system_id=1):
# 消息头固定 10 字节
# Length: 10 (只有头,无体)
length = 10
# Device ID: bit15=0 (Host→Equipment)
dev_id = device_id & 0x7FFF
# Stream/Function: Select.req 使用 S0F1
s_f = (0 << 8) | 1
# P/B Type: bit7=0, bit6=0, type=1 (Select.req)
pb_type = 1
# System Bytes: 4 字节,这里只演示高 8 位
sys_bytes = (system_id >> 24) & 0xFF
header = struct.pack('!IHHB', length, dev_id, s_f, pb_type)
header += struct.pack('!I', system_id)[:1] # 只取高 8 位
return header
# 发送示例
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.1.100', 5000))
msg = build_select_req()
sock.send(msg)
response = sock.recv(1024)
print(f'Received {len(response)} bytes')
sock.close()