github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/proto/v2/pcodec/codec.go (about)

     1  package pcodec
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"encoding/binary"
     7  )
     8  
     9  /*
    10  发送方在每次发送消息时将消息长度写入一个int32作为包头一并发送出去, 我们称之为Encode
    11  接受方则先读取一个int32的长度的消息长度信息, 再根据长度读取相应长的byte数据, 称之为Decode
    12  */
    13  func Encode(message string) ([]byte, error) {
    14  	// 读取消息的长度
    15  	var length int32 = int32(len(message))
    16  	var pkg *bytes.Buffer = new(bytes.Buffer)
    17  	// 写入消息头
    18  	err := binary.Write(pkg, binary.LittleEndian, length)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	// 写入消息实体
    23  	err = binary.Write(pkg, binary.LittleEndian, []byte(message))
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	return pkg.Bytes(), nil
    29  }
    30  
    31  func Decode(reader *bufio.Reader) (string, error) {
    32  	// 读取消息的长度
    33  	lengthByte, _ := reader.Peek(4)
    34  	lengthBuff := bytes.NewBuffer(lengthByte)
    35  	var length int32
    36  	err := binary.Read(lengthBuff, binary.LittleEndian, &length)
    37  	if err != nil {
    38  		return "", err
    39  	}
    40  	if int32(reader.Buffered()) < length+4 {
    41  		return "", err
    42  	}
    43  
    44  	// 读取消息真正的内容
    45  	pack := make([]byte, int(4+length))
    46  	_, err = reader.Read(pack)
    47  	if err != nil {
    48  		return "", err
    49  	}
    50  	return string(pack[4:]), nil
    51  }