package common import ( "bytes" "encoding/binary" "fmt" "github.com/lunixbochs/struc" "github.com/valyala/bytebufferpool" ) // TomeeHeader 结构体字段定义 type TomeeHeader struct { Len uint32 `json:"len"` Version byte `json:"version" struc:"[1]byte"` CMD uint32 `json:"cmdId" struc:"uint32"` UserID uint32 `json:"userId"` //Error uint32 `json:"error" struc:"skip"` Result uint32 `json:"result"` Data *bytebufferpool.ByteBuffer `json:"data" struc:"skip"` //组包忽略此字段// struc:"skip" Res []byte `struc:"skip"` //Return []byte `struc:"skip"` //返回记录 } func NewTomeeHeader(cmd uint32, userid uint32) *TomeeHeader { return &TomeeHeader{ CMD: cmd, // Len: 0, Version: 49, Result: 0, } } // Pack 组包方法:手动编码字节流,兼容interface{}、nil、多层指针/接口 func (h *TomeeHeader) Pack(data any) []byte { if data == nil { return h.packHeaderWithData([]byte{}) } var data1 bytes.Buffer err := struc.Pack(&data1, data) if err != nil { fmt.Println(err) } if len(data1.Bytes()) == 0 { // fmt.Println("数据为空") } //datar = data1.Bytes() // 4. 手动打包包头+数据体 return h.packHeaderWithData(data1.Bytes()) } // packHeaderWithData 手动编码包头和数据体(静态指定偏移量,无自增变量) // 包头固定结构(大端序): // - 0-3 字节:Len (uint32) // - 4 字节:Version (byte) // - 5-8 字节:CMD (uint32,从uint64截断) // - 9-12 字节:UserID (uint32) // - 13-16 字节:Result (uint32) // 17字节后:数据体 func (h *TomeeHeader) packHeaderWithData(data []byte) []byte { // 计算总长度:包头17字节 + 数据体长度 dataLen := len(data) h.Len = uint32(17 + dataLen) // 预分配切片(总长度 = 包头 + 数据体),避免多次扩容 buf := make([]byte, h.Len) // 1. 写入Len(固定偏移:0-3 字节,大端序) binary.BigEndian.PutUint32(buf[0:4], h.Len) // 2. 写入Version(固定偏移:4 字节) buf[4] = h.Version // 3. 写入CMD(固定偏移:5-8 字节,大端序) binary.BigEndian.PutUint32(buf[5:9], uint32(h.CMD)) // 4. 写入UserID(固定偏移:9-12 字节,大端序) binary.BigEndian.PutUint32(buf[9:13], h.UserID) // 5. 写入Result(固定偏移:13-16 字节,大端序) binary.BigEndian.PutUint32(buf[13:17], h.Result) // 6. 写入数据体(固定起始偏移:17 字节,若有数据则拷贝) if dataLen > 0 { copy(buf[17:], data) } return buf }