# frameio **Repository Path**: copperxcx/frameio ## Basic Information - **Project Name**: frameio - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-01 - **Last Updated**: 2026-02-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # frameio - 通用帧协议编解码工具包 [![Go Reference](https://pkg.go.dev/badge/gitee.com/copperxcx/frameio.svg)](https://pkg.go.dev/gitee.com/copperxcx/frameio) [![Go Report Card](https://goreportcard.com/badge/gitee.com/copperxcx/frameio)](https://goreportcard.com/report/gitee.com/copperxcx/frameio) [![Test Coverage](https://img.shields.io/badge/coverage-51.7%25-blue)](https://gitee.com/copperxcx/frameio) [![License](https://img.shields.io/badge/license-MIT-green)](https://gitee.com/copperxcx/frameio/blob/main/LICENSE) ## 项目介绍 `frameio` 是一个用 Go 语言编写的通用帧协议编解码工具包,专注于提供高效、稳定的帧结构处理能力。它支持自定义帧头标识、可配置的最大帧体长度,并提供了简单易用的 API 接口,适用于各种基于“帧头+帧体”结构的通信场景。 ## 功能特性 - **通用帧协议**:不依赖具体业务协议,支持任意帧体内容 - **灵活配置**:可自定义帧头标识和最大帧体长度 - **高效编解码**:优化的帧打包和解包算法 - **异步解码**:支持异步解码和回调机制 - **并发安全**:内部使用原子操作和读写锁,确保线程安全 - **IO 兼容性**:仅依赖 Go 标准库的 io.Reader 和 io.Writer 接口 - **错误处理**:提供清晰的错误类型和错误判断辅助函数 ## 安装 使用 `go get` 命令安装: ```bash go get gitee.com/copperxcx/frameio ``` ## 快速开始 ### 传统方式(分开创建编码器和解码器) ```go package main import ( "bytes" "fmt" "gitee.com/copperxcx/frameio" ) // 自定义帧类型 const ( FrameTypeCommand byte = 0x01 FrameTypeState byte = 0x02 ) func main() { // 1. 模拟 IO(bytes.Buffer 实现 io.Reader/io.Writer) buf := &bytes.Buffer{} // 2. 创建编码器(自定义帧头0xBB,最大帧体1024字节) encoder := frameio.NewEncoder(buf, frameio.WithFrameHeader(0xBB), frameio.WithMaxFrameBodyLen(1024), ) // 3. 创建解码器(与编码器配置一致) decoder := frameio.NewDecoder(buf, frameio.WithFrameHeader(0xBB), frameio.WithMaxFrameBodyLen(1024), ) // 4. 注册回调函数 decoder.RegisterCallback(FrameTypeState, func(frame *frameio.Frame) error { fmt.Printf("收到状态帧:序号=%d,帧体=%x\n", frame.Header.FrameNum, frame.Body) return nil }) // 5. 启动解码器(异步) go func() { if err := decoder.Start(); err != nil { fmt.Printf("解码失败:%v\n", err) } }() defer decoder.Stop() // 6. 打包并写入帧 commandBody := []byte("move_x:100") if err := encoder.WriteFrame(FrameTypeCommand, commandBody); err != nil { fmt.Printf("写入失败:%v\n", err) } // 7. 阻塞主线程 select {} } ``` ### 聚合接口方式(使用 FrameIO 同时进行编解码) ```go package main import ( "bytes" "fmt" "gitee.com/copperxcx/frameio" ) // 自定义帧类型 const ( FrameTypeCommand byte = 0x01 FrameTypeState byte = 0x02 ) func main() { // 1. 模拟 IO(bytes.Buffer 实现 io.Reader/io.Writer) buf := &bytes.Buffer{} // 2. 创建帧协议编解码器(聚合接口,自定义帧头0xBB,最大帧体1024字节) fio := frameio.NewFrameIO(buf, frameio.WithFrameHeader(0xBB), frameio.WithMaxFrameBodyLen(1024), ) // 3. 注册回调函数 fio.RegisterCallback(FrameTypeState, func(frame *frameio.Frame) error { fmt.Printf("收到状态帧:序号=%d,帧体=%x\n", frame.Header.FrameNum, frame.Body) return nil }) // 4. 启动解码器(异步) go func() { if err := fio.Start(); err != nil { fmt.Printf("解码失败:%v\n", err) } }() defer fio.Stop() // 5. 打包并写入帧 commandBody := []byte("move_x:100") if err := fio.WriteFrame(FrameTypeCommand, commandBody); err != nil { fmt.Printf("写入失败:%v\n", err) } // 7. 阻塞主线程 select {} } ``` ## 核心概念 ### 帧结构 `frameio` 使用固定的帧结构: | 字段名 | 字节长度 | 说明 | |-----------|----------|-------------------------------| | Header | 1 | 帧头标识(可配置,默认0xAA) | | Type | 1 | 帧类型(调用方自定义枚举值) | | FrameNum | 2 | 帧序号(自增,小端字节序) | | BodyLen | 2 | 帧体长度(字节数,小端字节序)| | Body | N | 帧体内容(N ≤ 最大帧体长度) | ### 编码器 (Encoder) 负责将帧类型和帧体打包成完整的帧,并写入到 IO 设备。 ### 解码器 (Decoder) 负责从 IO 设备读取字节流,解析帧结构,并根据帧类型触发相应的回调函数。 ## API 文档 ### 配置选项 ```go // 自定义帧头标识 func WithFrameHeader(header byte) Option // 自定义最大帧体长度 func WithMaxFrameBodyLen(len int) Option ``` ### 编码器方法 ```go // 构造编码器(传入io.Writer和配置选项) func NewEncoder(writer io.Writer, opts ...Option) *Encoder // 仅打包帧(不写入IO),返回完整帧对象 func (e *Encoder) PackFrame(frameType byte, body []byte) (*Frame, error) // 打包并写入IO(一步完成) func (e *Encoder) WriteFrame(frameType byte, body []byte) error // 直接写入已编码的帧字节流(支持自定义帧) func (e *Encoder) WriteRawFrame(frameBytes []byte) error ``` ### 解码器方法 ```go // 构造解码器(传入io.Reader和配置选项) func NewDecoder(reader io.Reader, opts ...Option) *Decoder // 注册帧类型回调函数 func (d *Decoder) RegisterCallback(frameType byte, callback FrameCallback) // 注销帧类型回调函数 func (d *Decoder) UnregisterCallback(frameType byte) // 启动解码循环(阻塞运行,直到调用Stop()或出错) func (d *Decoder) Start() error // 停止解码循环 func (d *Decoder) Stop() ``` ### 聚合接口 (FrameIO) `FrameIO` 是同时具备编码器和解码器功能的聚合接口,让您可以使用一个变量完成所有编解码操作。 ```go // 构造FrameIO(传入同时实现io.Reader和io.Writer的对象,如net.Conn) func NewFrameIO(rw io.ReadWriter, opts ...Option) *FrameIO // 构造FrameIO(传入分离的io.Reader和io.Writer) func NewFrameIOWithSeparateIO(reader io.Reader, writer io.Writer, opts ...Option) *FrameIO ``` `FrameIO` 嵌入了 `Encoder` 和 `Decoder` 结构体,因此具备以下所有方法: **编码器方法:** - `PackFrame(frameType byte, body []byte) (*Frame, error)` - 仅打包帧(不写入IO) - `WriteFrame(frameType byte, body []byte) error` - 打包并写入IO(一步完成) - `WriteRawFrame(frameBytes []byte) error` - 直接写入已编码的帧字节流 **解码器方法:** - `RegisterCallback(frameType byte, callback FrameCallback)` - 注册帧类型回调函数 - `UnregisterCallback(frameType byte)` - 注销帧类型回调函数 - `Start() error` - 启动解码循环(阻塞运行,直到调用Stop()或出错) - `Stop()` - 停止解码循环 ### 编解码辅助函数 ```go // 帧头编码为字节流 func (h *FrameHeader) Encode() ([]byte, error) // 从字节流解析帧头 func DecodeHeader(data []byte) (*FrameHeader, error) // 完整帧编码为字节流 func EncodeFrame(frame *Frame) ([]byte, error) // 从字节流解析完整帧 func DecodeFrame(data []byte, maxBodyLen int) (*Frame, error) ``` ## 错误处理 `frameio` 提供了以下自定义错误类型: ```go var ( ErrInvalidHeader = errors.New("frameio: invalid frame header") ErrFrameLenInsufficient = errors.New("frameio: insufficient total frame length") ErrBodyLenOverflow = errors.New("frameio: frame body length exceeds max limit") ErrUnknownFrameType = errors.New("frameio: unknown frame type (no callback registered)") ErrIOReadFailed = errors.New("frameio: read from io.Reader failed") ErrIOWriteFailed = errors.New("frameio: write to io.Writer failed") ErrWriteLenMismatch = errors.New("frameio: written length not equal to frame length") ) ``` 同时提供了错误判断辅助函数: ```go func IsInvalidHeader(err error) bool func IsUnknownFrameType(err error) bool func IsFrameLenInsufficient(err error) bool func IsBodyLenOverflow(err error) bool func IsIOReadFailed(err error) bool func IsIOWriteFailed(err error) bool func IsWriteLenMismatch(err error) bool ``` ## 测试 项目包含完整的单元测试,可以使用以下命令运行: ```bash # 执行所有测试 go test -v # 生成测试覆盖率报告 go test -v -coverprofile=coverage.out go tool cover -html=coverage.out ``` ## 贡献 欢迎提交 Issue 和 Pull Request 来改进项目。 ## 许可证 本项目使用 MIT 许可证,详情请查看 [LICENSE](LICENSE) 文件。