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. ARTS-S linux常用命令

    压缩 把文件夹test压缩成test.tar.gz tar -czvf test.tar.gz test centos同步网上时间 cp /usr/share/zoneinfo/Asia/Shangh ...

  2. Java多态之向上转型

    目录 Java多态之向上转型 多态的优点 向上转型 概念 向上转型好在哪 Java多态之向上转型 多态性是面向对象的第三大特征. 多态的优点 改善代码的组织结构和可读性. 能够创建可扩展的程序.(随时 ...

  3. checkbox多选框取值

    var SelectQuestionAnswer = $("input:checkbox[name='SelectQuestionAnswer']:checked").map(fu ...

  4. python将数据库修改,数据库操作同步到数据库中

    *****************数据库迁移(同步)命令******************************** 1.python manage.py makemigrations 将数据库的 ...

  5. Python 单线程下实现多个socket并发

    ## 客户端 import socket import gevent import threading import multiprocessing ip_bind = ('127.0.0.1',80 ...

  6. 2016/09/21 context.getConfiguration().get()

    查看api:http://hadoop.apache.org/docs/stable/api/ public String get(String name) Get the value of the ...

  7. 骚年,如果你还不懂一些java常识?中了奖也无法兑换

    今天下午约着几个朋友一起去看叶问4,结果碰到了一个有趣的事情,正好和java有关所以写一篇文章来记录一下. 事件:我和朋友小李.小王一起去看电影 时间:2019/12/21 地点:H市某家电影院 起因 ...

  8. 永恒之蓝及WannaCry分析

    以下部分是我的一次大作业,写了大概有一周,拿出来凑篇博客,如果有错误的地方,还请指正.粘贴过程中可能图片有错误. 1.环境搭建及简介 1.1 实验环境 Windows 7 (靶机) Parrot(攻击 ...

  9. python 多线程编程之threading模块(Thread类)创建线程的三种方法

    摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...

  10. 服务发现(consul)搭建

    服务发现(consul)搭建 下载最新版 consul 本人使用的版本为1.5.1,操作系统:window server 2008 consul部署的时候分为客户端和服务端,本次操作服务器2台,客户端 ...