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()
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}

结果就是上面的样子,解出来就可以去用了

最新文章

  1. 【原】AFNetworking源码阅读(四)
  2. EL表达式的使用
  3. Python学习路程-常用设计模式学习
  4. java_method_下载导入模版
  5. 利用Solr服务建立的站内搜索雏形---solr1
  6. Maven_pom.xml介绍
  7. C#连接Oracle简单教程
  8. 上传系列:ajaxupload.js
  9. 【C++11】新特性——Lambda函数
  10. Windows Phone开发(13):如何规范用户的输入行为
  11. Protocol Buffer序列化对比Java序列化.
  12. 最新webstorm
  13. UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
  14. Centos下安装Mysql异常
  15. scala模式匹配及样本类
  16. Hyperledger Fabric密码模块系列之BCCSP(三)
  17. C# MD5 加密,解密
  18. unity3d 九宫密码锁
  19. USACO 5.1 Starry Night
  20. HttpServletRequest介绍

热门文章

  1. Spring Boot 搭建TCP Server
  2. nbuoj2784 倒水
  3. HDU3710 Battle over Cities(最小生成树+树链剖分+倍增+线段树)
  4. F#周报2019年第50期
  5. Jenkins-部署java代码项目
  6. 深入理解Linux的I/O复用之epoll机制
  7. 【Java Web开发学习】Spring消息-ActiveMQ发送消息
  8. JSP注册登录页教程
  9. 将数据库中数据导出为excel表格
  10. [从今天开始修炼数据结构]队列、循环队列、PriorityQueue的原理及实现