golang tpc 粘包处理

使用分隔符号

分隔符编码
点击查看代码
func DelimeterEncode(message string) ([]byte, error) {

	var pkg = new(bytes.Buffer)
	err := binary.Write(pkg, binary.BigEndian, []byte(message))
	if err != nil {
		return nil, err
	}

	return []byte(message + "\n"), nil
}

分隔符解码

点击查看代码
func DelimeterDecode(reader *bufio.Reader) {
	data, err := reader.ReadSlice('\n')
	if err != nil {
		if err != io.EOF {
			log.Println(err)
		} else {
			return
		}
	}
	log.Println("received msg", len(data), "bytes:", string(data))
}

使用固定长度

编码

点击查看代码
func Encode(message string) ([]byte, error) {
	var length = int32(len(message))

	var pkg = new(bytes.Buffer)
	err := binary.Write(pkg, binary.BigEndian, length)
	if err != nil {
		return nil, err
	}

	err = binary.Write(pkg, binary.BigEndian, []byte(message))
	if err != nil {
		return nil, err
	}

	return pkg.Bytes(), nil
}

解码

点击查看代码
func Decode(reader *bufio.Reader) {

	peek, err := reader.Peek(4)
	if err != nil {
		if err != io.EOF {
			log.Println(err)
		} else {
			return
		}
	}

	buffer := bytes.NewBuffer(peek)
	var length int32
	err = binary.Read(buffer, binary.BigEndian, &length)
	if err != nil {
		log.Println(err)
	}
	if int32(reader.Buffered()) < length+4 {
		return
	}

	data := make([]byte, length+4)
	_, err = reader.Read(data)
	if err != nil {
		return
	}

	log.Println("received msg", string(data[4:]))
}

使用结构图基本类型 不包含 变长 例如 string slice

编码
点击查看代码
func structEncode(t struct{}) ([]byte, error) {

	pkg := &bytes.Buffer{}
	err := binary.Write(pkg, binary.BigEndian, t)
	if err != nil {
		return nil, err
	}
	return pkg.Bytes(), nil
}
#### 解码
点击查看代码
func structDecode(reader *bufio.Reader) (*struct{}, error) {
	t := struct{}{}
	err := binary.Read(reader, binary.BigEndian, &t)
	if err != nil {
		return nil, err
	}

	log.Println("received msg", t)

	return &t, nil

}

tcp 通讯样例

服务端代码
点击查看代码
func main() {
	listener, err := net.Listen("tcp", "127.0.0.1:8866")
	if err != nil {
		log.Fatal(err)
	}
	defer listener.Close()

	for {
		con, err := listener.Accept()
		if err != nil {
			log.Println(err)
			continue
		}
		defer con.Close()

		reader := bufio.NewReader(con)
		for {
			pack.Decode(reader)
		}
	}
}

客户端

点击查看代码
func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8866")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	for i := 0; i < 10; i++ {
		var err error
		var data []byte

		data, err = pack.Encode(strconv.Itoa(i) + "aaaa")
		_, err = conn.Write(data)

		data, err = pack.Encode(strconv.Itoa(i) + "bbbb")
		_, err = conn.Write(data)

		data, err = pack.Encode(strconv.Itoa(i) + "ccccc")
		_, err = conn.Write(data)

		if err != nil {
			panic(err)
		}
	}
	time.Sleep(time.Second)
}
posted @ 2022-11-02 11:16  vx_guanchaoguo0  阅读(46)  评论(0编辑  收藏  举报