- SetData 超长时 fmt.Errorf 结果未 return,超 65535 字节静默放行 → 改为返回错误 - ReadFrame 原实现 conn.Read 直读帧头(短读错位)且一次性 bufio.Reader 会丢弃 缓冲中的后续帧字节 → 统一改 io.ReadFull 精确读取,新增连续两帧回归测试 - 补齐单元测试(往返/流水线/超长/Marshal/RawHeader)、examples/frame 例程与 README
frame
应用层帧协议:头 8 字节(版本 1 + 命令 1 + 长度 2 + 流 ID 4,小端序)+ 数据,
提供帧与 net.Conn 间的读写封装,配合 JSON 编解码使用。
迁移自 go-hua/common/frame.go,独立成包。
帧格式
+---------+---------+-----------+-----------+----------------+
| ver (1) | cmd (1) | length(2) | sid (4) | data (length) |
+---------+---------+-----------+-----------+----------------+
小端序,length 最大 65535
用法
import (
"net"
"git.zeroonesoft.cn/golib/zogo/frame"
)
// 组帧:版本 + 命令字 + 流 ID,数据可 Marshal 任意 JSON 值
f := frame.NewFrame(frame.FrameVersion, 0x10, 42)
f.Marshal(map[string]any{"msg": "hello"})
// 连接上写帧 / 读帧(阻塞直到完整帧)
frame.WriteFrame(conn, f)
got, err := frame.ReadFrame(conn)
var data map[string]any
got.Unmarshal(&data)
完整可运行例程:examples/frame/main.go
迁移修复(相对 go-hua/common 原实现)
- SetData 超长未报错:原实现
fmt.Errorf结果未 return,超长数据静默截断写入; 现超 65535 字节正确返回错误(有回归测试)。 - ReadFrame 短读/吞字节:原实现直接
conn.Read读头(TCP 分段会错位),且用 一次性bufio.Reader读体(缓冲里多读到的后续帧字节随 reader 丢弃)。现统一改用io.ReadFull精确读取,连续多帧不丢数据(有回归测试)。
注意
- 单帧数据上限 65535 字节(length 字段 2 字节),更大 payload 请业务侧分片。
ReadFrame/WriteFrame非并发安全,同一连接的读与写可各由一个 goroutine 持有。