[Go] 轻量服务器框架tcp的粘包问题 封包与拆包
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() []byte { return m.Data } func (m *Message) GetMsgLen() uint32 { return m.MsgLen } func (m *Message) SetId(id uint32) { m.Id = id } func (m *Message) SetData(data []byte) { m.Data = data } func (m *Message) SetMsgLen(len uint32) { m.MsgLen = len }
封装一个封包解包的结构体,包括封包和解包的方法,封包就是先写长度,再写编号,再写数据;解包只是获取下长度和编号,数据下次再取
package znet import "zinx/zinterface" import "bytes" import "encoding/binary" type DataPack struct { } func NewDataPack() *DataPack { dp := &DataPack{} return dp } func (dp *DataPack) Pack(m zinterface.IMessage) ([]byte, error) { dataBuff := bytes.NewBuffer([]byte{}) binary.Write(dataBuff, binary.LittleEndian, m.GetMsgLen()) binary.Write(dataBuff, binary.LittleEndian, m.GetId()) binary.Write(dataBuff, binary.LittleEndian, m.GetData()) return dataBuff.Bytes(), nil } func (dp *DataPack) Unpack(d []byte) (zinterface.IMessage, error) { m := NewMessage() r := bytes.NewReader(d) binary.Read(r, binary.LittleEndian, &m.MsgLen) binary.Read(r, binary.LittleEndian, &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,_:=dp.Unpack(dataPack) log.Println(m2)
2019/12/17 15:42:30 &{888 [110 105 104 97 111] 5}
2019/12/17 15:42:30 [5 0 0 0 120 3 0 0 110 105 104 97 111]
2019/12/17 15:42:30 &{888 [] 5}
结果就是上面的样子,解出来就可以去用了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具