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}

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

[Go] 轻量服务器框架tcp的粘包问题 封包与拆包的更多相关文章

  1. [Go] 轻量服务器框架基础TCP服务模块

    框架要先把整体的结构定义好,一般都是在$GOPATH目录的src下建立自己的目录 zinterface是一些接口的定义 znet就是接口的具体实现 IServer.go package zinterf ...

  2. [Go] 轻量服务器框架基础TCP连接的抽象和封装

    对tcp连接部分以及与连接绑定的业务部分进行抽象和封装 主要是对连接的开启关闭和读写进行封装,抽象出接口,使用回调进行具体业务的绑定 zinterface/iconnection.go package ...

  3. [Go] 轻量服务器框架全局配置的实现以及解析json

    在一个应用中经常需要有一个配置文件,可以对代码中的参数进行配置,可以使用一个json文件来对应一个struct的对象,进行全局配置 建一个conf/zinx.json作为配置文件 { "Na ...

  4. 阿里云轻量服务器价格及轻量与ECS服务器区别比较

    https://yq.aliyun.com/articles/221647 摘要: 阿里云轻量应用服务器价格表及介绍,关于轻量应用服务器和ECS服务器的性能对比 阿里云轻量应用服务器是阿里云新推出的服 ...

  5. TCP的粘包现象

    看面经时,看到有面试官问TCP的粘包问题.想起来研一做购物车处理数据更新时遇到粘包问题,就总结一下吧. 1 什么是粘包现象 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看, ...

  6. python 全栈开发,Day35(TCP协议 粘包现象 和解决方案)

    一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...

  7. TCP通信粘包问题分析和解决

    转载至https://www.cnblogs.com/kex1n/p/6502002.html 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发 ...

  8. TCP通信粘包问题分析和解决(全)(转)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  9. C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性

    C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性 上节我们讲到了socket缓冲区和数据的传递过程,可以看到数据的接收和发送是无关的,read()/recv() 函数不管数据发 ...

随机推荐

  1. POJ 2186 Popular cows(SCC 缩点)

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10, ...

  2. enumerate用法总结

    enumerate在字典上是枚举.列举的意思 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值 enumerat ...

  3. Python3 函数进阶1

    目录 闭包函数 什么是闭包函数 闭包函数的作用 装饰器 什么是装饰器 无参装饰器 有参装饰器 闭包函数 什么是闭包函数 闭包函数本质上就是函数嵌套和高阶函数 闭包函数的满足条件: 必须嵌套函数 内嵌函 ...

  4. elasticsearch搜索QueryStringQueryBuilder时的一些问题记录

    首先看下原始数据 但是 如果使用英文查询的时候又和上面有点区别了,感觉还是分词器的问题

  5. java虚拟机运行内存图

    首先针对8种常见数据类型(byte,short,int,long,double,float,char,boolean),还有String,他们在类对象被引用的时候,把数据类型存放在栈中,而常量则放在常 ...

  6. 35个Java代码优化的细节,你知道几个?

    前言 代码 优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没 ...

  7. python基础入门 列表

    列表 1.关键字---list 2.定义:用来存储数据可存储多种数据类型 支持索引,切片 是有序的 可变的 3.定义一个列表 l1 = ['列表','字符串','lnh',123,'kk0','ttt ...

  8. Appium移动端自动化测试--控件定位方法

    常用定位手段 id Accessibility ID XPath 控件基础知识 DOM: Document Object Model文档对象模型 DOM应用:最早应用于HTML和Javascript的 ...

  9. ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇

    题外话 笔者有个习惯,就是在接触新的东西时,一定要先搞清楚新事物的基本概念和背景,对之有个相对全面的了解之后再开始进入实际的编码,这样做最主要的原因是尽量避免由于对新事物的认知误区导致更大的缺陷,Bu ...

  10. ESLint + Prettier + husky + lint-staged 规范统一前端代码风格

    写在前面: ESLint: Find and fix problems in your JavaScript code. Prettier: Prettier is an opinionated co ...