[Go] 轻量服务器框架tcp的粘包问题 封包与拆包
发布时间:2021-05-21 06:48:01 所属栏目:大数据 来源: https://www.jb51.cc
导读:tcp传输的数据是以流的形式传输的,因此就没有办法判断到哪里结束算是自己的一个消息,这样就会出现粘包问题,多个包粘在一起了 可以使用这样一个自定义的形式来解决,一个消息分为 head+body? head包括数据的长度和数据编号 , 长度和编号都是uint32类型 也
tcp传输的数据是以流的形式传输的,因此就没有办法判断到哪里结束算是自己的一个消息,这样就会出现粘包问题,多个包粘在一起了 可以使用这样一个自定义的形式来解决,一个消息分为 head+body? head包括数据的长度和数据编号 , 长度和编号都是uint32类型 也就是32位 占有4个字节 , 总共head占有8个字节 封装一个消息的结构体,作为一个数据实体,比如下面这个,编号 数据 数据长度? 三个属性 package znet type Message struct { Id uint32 Data []byte MsgLen uint32 } func NewMessage() *Message { m := &Message{} return m } func (m *Message) GetId() uint32 { return m.Id } func (m *Message) GetData() [] { return m.Data } func (m *Message) GetMsgLen() uint32 { return m.MsgLen } func (m *Message) SetId(id uint32) { m.Id = } func (m *Message) SetData(data []) { m.Data = data } func (m *Message) SetMsgLen(len uint32) { m.MsgLen = len } 封装一个封包解包的结构体,包括封包和解包的方法,封包就是先写长度,再写编号,再写数据;解包只是获取下长度和编号,数据下次再取 package znet import "zinx/zinterface" import bytesencoding/binary type DataPack struct { } func NewDataPack() *DataPack { dp := &DataPack{} return dp } func (dp *DataPack) Pack(m zinterface.IMessage) ([],error) { dataBuff := bytes.NewBuffer([]{}) binary.Write(dataBuff,binary.LittleEndian,m.GetMsgLen()) binary.Write(dataBuff,m.GetId()) binary.Write(dataBuff,m.GetData()) return dataBuff.Bytes(),nil } func (dp *DataPack) Unpack(d []) (zinterface.IMessage,error) { m := NewMessage() r := bytes.NewReader(d) binary.Read(r,&m.MsgLen) binary.Read(r,1)">m.Id) return m,nil } 测试,先封包再解包 body:=[]byte(nihao) m:=znet.NewMessage() m.SetId(888) m.SetData(body) m.SetMsgLen(uint32(len(body))) log.Println(m) dp:=znet.NewDataPack() dataPack,_:=dp.Pack(m) log.Println(dataPack) m2,1)">dp.Unpack(dataPack) log.Println(m2) 2019/12/17 15:42:30 &{888 [110 105 104 97 111] 5} 结果就是上面的样子,解出来就可以去用了 ? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |