github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/poller/cmd/common/codec_client.go (about) 1 package common 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "net" 8 9 "github.com/weedge/lib/poller" 10 ) 11 12 // Codec 编解码器,用来处理tcp的拆包粘包 13 type Codec struct { 14 Conn net.Conn 15 ReadBuf *poller.Buffer // 读缓冲 16 } 17 18 // NewCodec 创建一个编解码器 19 func NewCodec(conn net.Conn) *Codec { 20 return &Codec{ 21 Conn: conn, 22 ReadBuf: poller.NewBuffer(make([]byte, MaxLen)), 23 } 24 } 25 26 // Read 从conn里面读取数据,当conn发生阻塞,这个方法也会阻塞 27 func (c *Codec) Read() (int, error) { 28 return c.ReadBuf.ReadFromReader(c.Conn) 29 } 30 31 // Decode 解码数据 32 // Package 代表一个解码包 33 // bool 标识是否还有可读数据 34 func (c *Codec) Decode() ([]byte, bool, error) { 35 var err error 36 // 读取数据长度 37 lenBuf, err := c.ReadBuf.Seek(HeaderLen) 38 if err != nil { 39 return nil, false, nil 40 } 41 42 // 读取数据内容 43 valueLen := int(binary.BigEndian.Uint16(lenBuf)) 44 45 // 数据的字节数组长度大于buffer的长度,返回错误 46 if valueLen > MaxLen { 47 fmt.Println("out of max len") 48 return nil, false, errors.New("out of max len") 49 } 50 51 valueBuf, err := c.ReadBuf.Read(HeaderLen, valueLen) 52 if err != nil { 53 return nil, false, nil 54 } 55 return valueBuf, true, nil 56 } 57 58 // Encode 编码数据 59 func Encode(bytes []byte) []byte { 60 l := len(bytes) 61 buffer := make([]byte, l+HeaderLen) 62 // 将消息长度写入buffer 63 binary.BigEndian.PutUint16(buffer[0:HeaderLen], uint16(l)) 64 // 将消息内容内容写入buffer 65 copy(buffer[HeaderLen:], bytes) 66 return buffer[0 : HeaderLen+l] 67 }