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  }