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)
}
本文来自博客园,作者:vx_guanchaoguo0,转载请注明原文链接:https://www.cnblogs.com/guanchaoguo/p/16850424.html