栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

go TCP 粘包原理和解决方案

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

go TCP 粘包原理和解决方案

1 为什么会出现粘包

主要原因是tcp 数据传递模式是留模式,在长连接过程中可以进行多次收发。数据粘包可以发生在客户端和服务端。

2 解决办法

出现粘包的关键在于不确定包的大小,因此可以通过封包将把的内容长度封装在包头,用固定长度的值来存储包内容长度。自己封装一个数据传输协议。如下:

package proto

import (
    "bufio"
    "bytes"
    "encoding/binary"
)

// Encode 将消息编码
func Encode(message string) ([]byte, error) {
    var length = int32(len(message)) // 读取消息的长度,转换成int32类型(占4个字节)
    var pkg = new(bytes.Buffer) // 定义一个空的bytes 缓冲区
    // 写入消息头
    err := binary.Write(pkg, binary.LittleEndian, length) //通过小端序列的方式把length 写到pkg。binary.LittleEndian 为编码格式
    if err != nil {
        return nil, err
    }
    // 写入消息实体
    err = binary.Write(pkg, binary.LittleEndian, []byte(message)) //在通过小端序列的方式把真实的包内容写入bytes,封装成一个包。
    if err != nil {
        return nil, err
    }
    return pkg.Bytes(), nil // 返回封装好的包
}

// Decode 解码消息
func Decode(reader *bufio.Reader) (string, error) {
    lengthByte, _ := reader.Peek(4) // 读取前4个字节的数据,及包的内容长度,endoce 里面的length。Peek的方式读取内容,是不会清掉缓存的
    lengthBuff := bytes.NewBuffer(lengthByte) //定义一个以lengthByte为内容的bytes缓冲区
    var length int32
    err := binary.Read(lengthBuff, binary.LittleEndian, &length)// 将lengthBuff 的内容写到length里面。这里要相应解码才能读取到length的内容
    if err != nil {
        return "", err
    }
    // Buffered返回缓冲中现有的可读取的字节数。前面用Peek读取,所以这里数据内容应该大于length+4
    if int32(reader.Buffered()) < length+4 {
        return "", err
    }

    // 读取真正的消息数据
    pack := make([]byte, int(4+length)) // 创建字节切片
    _, err = reader.Read(pack) 
    if err != nil {
        return "", err
    }
    return string(pack[4:]), nil //返回去掉length的字符串
}

后续在客户端发送消息的时候编码,读写的时候解码就行了

// 客户端
msg := `Hello, Hello. How are you?`
data, err := proto.Encode(msg)
conn.Write(data)
//服务端
msg, err := proto.Decode(reader)
if err == io.EOF {
    return
}
if err != nil {
    fmt.Println("decode msg failed, err:", err)
    return
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/904154.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号