Files
bl/common/socket/codec/SocketCodec_Tomee.go

86 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package codec
import (
"encoding/binary"
"errors"
"io"
"github.com/panjf2000/gnet/v2"
)
var ErrIncompletePacket = errors.New("incomplete packet")
// TomeeSocketCodec 协议格式:
//
// * 0 4
// * +-----------+
// * | body len |
// * +-----------+
// * | |
// * + +
// * | body bytes|
// * + +
// * | ... ... |
// * +-----------+
type TomeeSocketCodec struct{}
var _ SocketCodec = (*TomeeSocketCodec)(nil)
func NewTomeeSocketCodec() *TomeeSocketCodec {
return &TomeeSocketCodec{}
}
func (codec TomeeSocketCodec) Encode(buf []byte) ([]byte, error) {
bodyLen := len(buf)
data := make([]byte, 4+bodyLen)
// 写入4字节的包长度
binary.BigEndian.PutUint32(data[:4], uint32(bodyLen))
// 写入包体
copy(data[4:], buf)
return data, nil
}
func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
const maxBodyLen = 10 * 1024 * 1024 // 业务最大包体长度,按需调整
// 1. 读取4字节长度头
lenBuf, err := c.Peek(4)
if err != nil {
if errors.Is(err, io.ErrShortBuffer) {
return nil, ErrIncompletePacket
}
return nil, err
}
// 2. 解析长度并校验上限
bodyLen := binary.BigEndian.Uint32(lenBuf)
if bodyLen > maxBodyLen {
return nil, errors.New("packet body exceeds max length")
}
totalLen := 4 + int(bodyLen) // 总包长=长度头(4)+包体
// 3. 检查整个包是否完整关键修复用totalLen判断
fullBuf, err := c.Peek(totalLen)
if err != nil {
if errors.Is(err, io.ErrShortBuffer) {
return nil, ErrIncompletePacket
}
return nil, err
}
// 4. 提取包体关键修复跳过前4字节长度头
body := make([]byte, bodyLen)
copy(body, fullBuf[4:]) // 从fullBuf[4:]开始拷贝,仅取包体
// 5. 丢弃已解析的完整数据
_, err = c.Discard(totalLen) // 原代码用_忽略err建议处理可选
if err != nil {
return nil, err
}
return body, nil
}