千家信息网

go语言如何处理TCP拆包/粘包

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要讲解了"go语言如何处理TCP拆包/粘包",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"go语言如何处理TCP拆包/粘包"吧!part 1最
千家信息网最后更新 2026年11月04日go语言如何处理TCP拆包/粘包

这篇文章主要讲解了"go语言如何处理TCP拆包/粘包",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"go语言如何处理TCP拆包/粘包"吧!

part 1

最近在学习go自带的rpc,看完了一遍想着自己实现一个codec,也就是自定义消息的序列化和反序列化。消息的序列化和反序列化涉及到两步:

1、从网络中读取数据和将数据写到网络中;

2、根据拿到的二进制数据反序列化以及把现有的对象序列化成二进制数据。而这个过程中就需要处理TCP的拆包粘包了。

TCP的拆包/粘包也算是网络编程中一个比较基础的问题了,具体的问题含义和解决方式也不再详细描述了。虽然作为实现应用层逻辑的程序员可能根本不需要关心这个,作为中间件的开发,同时也出于学习go语言的目的,还是稍微进行一下练习。

part 2

TCP拆包粘包的解决思路:在读取数据时,将读取到的二进制数据在正确的位置进行分割即可。这里直接使用head+body的方式,也就是在发送数据时先将整个数据的大小附加在数据前,就像这样:

+++++++++++++++++++++++++++++++++++++
size (2 bytes) | body (size bytes)
+++++++++++++++++++++++++++++++++++++

这里将数据包的size作为head
注:这里举的例子里,size占2个byte;size具体占用的byte数可以根据实际情况决定

part 3

server具体实现:

func doConn(conn net.Conn) {    var (        buffer = bytes.NewBuffer(make([]byte, 0, BUF_SIZE)) //buffer用来缓存读取到的数据        readBytes = make([]byte, BUF_SIZE) //readBytes用来接收每次读取的数据,每次读取完成之后将readBytes添加到buffer中        isHead = true //用来标识当前的状态:正在处理size部分还是body部分        bodyLen = 0 //表示body的长度    )    for {        //首先读取数据        readByteNum, err := conn.Read(readBytes)        if err != nil {            log.Fatal(err)            return        }        buffer.Write(readBytes[0:readByteNum])//将读取到的数据放到buffer中                // 然后处理数据        for {            if isHead {                if buffer.Len() >= HEAD_SIZE {                    isHead = false                    head := make([]byte, HEAD_SIZE)                    _, err = buffer.Read(head)                    if err != nil {                        log.Fatal(err)                        return                    }                    bodyLen = int(binary.BigEndian.Uint16(head))                } else {                    break;                }            }            if !isHead {                if buffer.Len() >= bodyLen {                    body := make([]byte, bodyLen)                    _, err = buffer.Read(body[:bodyLen])                    if err != nil {                        log.Fatal(err)                        return                    }                    fmt.Println("received body: " + string(body[:bodyLen]))                    isHead = true                } else {                    break;                }            }        }    }        func HandleTcp() { listener, err := net.Listen("tcp", ":1234") if err != nil {  log.Fatal(err)  return } log.Println("start listening on 1234") for {  conn, err := listener.Accept()  if err != nil {   log.Fatal(err)   return  }  go doConn(conn) }}

client具体实现:

func SendStringwithTcp(arg string) error { conn, err := net.Dial("tcp", ":1234") if err != nil {  log.Fatal(err)  return err } head := make([]byte, server.HEAD_SIZE) content := []byte(arg) headSize := len(content) binary.BigEndian.PutUint16(head, uint16(headSize))    //先写入head部分,再写入body部分 _, err = conn.Write(head) if err != nil {  log.Fatal(err)  return err } _, err = conn.Write(content) if err != nil {  log.Fatal(err)  return err } return nil}

感谢各位的阅读,以上就是"go语言如何处理TCP拆包/粘包"的内容了,经过本文的学习后,相信大家对go语言如何处理TCP拆包/粘包这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

数据 序列 语言 学习 部分 二进制 网络 问题 处理 也就是 内容 思路 情况 方式 消息 还是 中间件 位置 例子 同时 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司 山东特亿宝互联网科技有限公司 互联网核心科技是什么 互联网扶贫科技 美国互联网科技巨头监管 科技创新互联网企业 易通互联网络科技有限公司 亿人帮互联网科技 互联网科技宣传片 互联网科技生活的内容 无锡溥仪互联网科技有限公司 太原新华互联网科技学校怎么样 老年人脱离互联网科技的作文 须眉科技是互联网公司吗 承德科技产业互联网发展 崇明区互联网教育科技诚信经营 互联网5g黑科技有哪些 华夏恒生互联网科技013171 广州新华互联网科技学校电竞方面 美国五大互联网科技公司市值多少 互联网科技名片 北京互联网科技 海南科技产业互联网平台 汉立互联网科技有限公司联系电话 迪庆互联网科技招生 深圳艾果互联网通讯科技 科技互联网的核心竞争力 35岁以上互联网科技行业 广州有谷有贝互联网科技有限公司 版纳互联网科技选哪家
0