3、HSMS高速通信标准:TCP/IP网络基础、HSMS连接建立与断开、HSMS报文格式与超时管理
3.1 TCP/IP网络基础与HSMS协议栈
HSMS(High-Speed SECS Message Services)是SECS/GEM协议族中基于TCP/IP的高速通信标准。它将原本基于RS-232串口的SECS-I协议迁移到以太网环境,大幅提升了数据传输速率与可靠性。
HSMS协议栈在OSI模型中的位置如下:
| OSI层 | HSMS协议栈 | 说明 |
|---|---|---|
| 应用层 | SECS-II / GEM | 设备状态、数据收集、报警管理 |
| 表示层 | SECS-II 消息编码 | SML格式、Item编码 |
| 会话层 | HSMS 会话管理 | 连接建立、心跳、断开 |
| 传输层 | TCP | 可靠字节流、拥塞控制 |
| 网络层 | IP | 路由、寻址 |
| 链路层 | 以太网 | MAC地址、帧封装 |
关键概念:HSMS使用TCP端口号5000作为默认通信端口。设备作为TCP客户端(主动发起连接)或服务器(被动等待连接),由配置决定。
3.2 HSMS连接建立与断开
HSMS定义了两种连接模式:主动模式(Active Mode)和被动模式(Passive Mode)。连接建立过程遵循三次握手原则,但增加了SECS/GEM特有的会话协商。
3.2.1 连接建立流程
- TCP三次握手:主动方发送SYN,被动方回复SYN+ACK,主动方发送ACK,建立TCP连接。
- HSMS Select.indication:主动方发送Select.req消息,请求建立HSMS会话。
- HSMS Select.confirm:被动方回复Select.rsp,确认会话建立成功。
- 通信开始:双方进入数据交换状态,可发送SECS-II消息。
实践要点:HSMS连接建立后,设备必须发送Separate.req消息来主动断开连接,而不是直接关闭TCP套接字。这保证了对方能收到明确的断开通知。
3.2.2 连接断开流程
- 正常断开:一方发送Separate.req,对方回复Separate.rsp,然后关闭TCP连接。
- 异常断开:TCP连接意外中断(如网络故障、设备断电),对方通过超时检测发现连接丢失。
- 心跳机制:通过Linktest.req/Linktest.rsp消息定期检测连接活性,默认间隔10秒。
3.3 HSMS报文格式
HSMS报文由消息头(Header)和消息体(Body)组成。消息头固定为10字节,消息体为可选的SECS-II数据。
3.3.1 消息头结构
| 字节偏移 | 字段 | 长度(字节) | 说明 |
|---|---|---|---|
| 0-1 | Length | 2 | 消息体长度(不含Header),大端序 |
| 2 | Device ID | 1 | 设备ID(低7位有效,bit7为控制位) |
| 3 | Stream | 1 | SECS-II Stream编号 |
| 4 | Function | 1 | SECS-II Function编号 |
| 5 | PType | 1 | 协议类型(0=SECS-II) |
| 6 | SType | 1 | 会话类型(0=Data Message, 1=Select.req, 2=Select.rsp, ...) |
| 7 | System Bytes | 2 | 系统字节,用于消息配对 |
| 9 | (保留) | 1 | 填充字节,通常为0 |
注意:System Bytes字段用于匹配请求与响应。发送方必须为每条消息分配唯一的System Bytes值,接收方在响应中回传相同的值。这是HSMS消息事务管理的基础。
3.3.2 会话类型(SType)定义
| SType值 | 消息类型 | 方向 |
|---|---|---|
| 0 | Data Message | 双向 |
| 1 | Select.req | 主动→被动 |
| 2 | Select.rsp | 被动→主动 |
| 3 | Deselect.req | 双向 |
| 4 | Deselect.rsp | 双向 |
| 5 | Linktest.req | 双向 |
| 6 | Linktest.rsp | 双向 |
| 7 | Reject.req | 双向 |
| 8 | Separate.req | 双向 |
3.4 超时管理
HSMS定义了多个超时定时器,用于保证通信的可靠性。超时管理是HSMS协议稳定运行的核心机制。
3.4.1 超时参数表
| 超时名称 | 默认值 | 说明 |
|---|---|---|
| T3 | 45秒 | 等待回复超时(Reply Timeout) |
| T5 | 10秒 | 连接建立超时(Connect Timeout) |
| T6 | 5秒 | 等待Select.rsp超时(Select Timeout) |
| T7 | 10秒 | Linktest间隔(Linktest Interval) |
| T8 | 5秒 | 等待Linktest.rsp超时(Linktest Timeout) |
3.4.2 超时处理策略
- T3超时:发送方未在45秒内收到回复,重发消息或报告错误。
- T5超时:TCP连接未在10秒内建立,重试或切换IP地址。
- T6超时:Select.req发送后5秒未收到Select.rsp,关闭连接并重试。
- T7超时:每10秒发送一次Linktest.req,检测连接活性。
- T8超时:Linktest.req发送后5秒未收到Linktest.rsp,认为连接断开。
3.5 实践案例:HSMS连接建立代码示例
以下是一个简化的HSMS连接建立代码片段,展示了主动方如何发起Select.req并处理响应:
// 伪代码:HSMS主动方连接建立
int device_id = 0x01;
int system_bytes = 0x1001;
// 1. 建立TCP连接
tcp_connect("192.168.1.100", 5000);
// 2. 构造Select.req消息头
uint8_t header[10];
header[0] = 0x00; // Length high (消息体长度为0)
header[1] = 0x00; // Length low
header[2] = (device_id & 0x7F) | 0x80; // Device ID + 控制位
header[3] = 0x00; // Stream (未使用)
header[4] = 0x00; // Function (未使用)
header[5] = 0x00; // PType = SECS-II
header[6] = 0x01; // SType = Select.req
header[7] = (system_bytes >> 8) & 0xFF; // System Bytes high
header[8] = system_bytes & 0xFF; // System Bytes low
header[9] = 0x00; // 保留字节
// 3. 发送Select.req
tcp_send(header, 10);
// 4. 启动T6超时定时器(5秒)
start_timer(T6, 5000);
// 5. 等待Select.rsp
uint8_t response[10];
int len = tcp_receive(response, 10, 5000);
if (len == 10 && response[6] == 0x02) {
// SType = Select.rsp
if (response[4] == 0x00) {
// 连接建立成功
stop_timer(T6);
printf("HSMS Session SELECTED\n");
} else {
// 连接被拒绝
printf("Select rejected, error code: %d\n", response[4]);
}
} else {
// T6超时或数据错误
printf("T6 timeout or invalid response\n");
tcp_close();
}
工程建议:在实际项目中,建议将HSMS连接管理封装为独立的状态机模块,使用事件驱动方式处理超时、重连和心跳。避免在主循环中阻塞等待网络数据。
3.6 本章小结
- HSMS基于TCP/IP,使用端口5000,支持主动/被动两种连接模式。
- 连接建立经过TCP三次握手和HSMS Select协商两个阶段。
- 报文格式固定:10字节消息头 + 可变长度消息体。
- 超时管理(T3/T5/T6/T7/T8)是保证通信可靠性的关键。
- Linktest心跳机制用于检测连接活性,防止“死连接”。