iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >go语言处理TCP拆包/粘包的具体实现
  • 511
分享到

go语言处理TCP拆包/粘包的具体实现

GOgo语言 2022-06-07 20:06:20 511人浏览 独家记忆
摘要

目录part 1part 2part 3part 1 最近在学习Go自带的rpc,看完了一遍想着自己实现一个codec,也就是自定义消息的序列化和反序列化。消息的序列化和反序

目录

part 1

part 2

part 3

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拆包/粘包内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!


您可能感兴趣的文档:

--结束END--

本文标题: go语言处理TCP拆包/粘包的具体实现

本文链接: https://www.lsjlt.com/news/30719.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • go语言如何处理TCP拆包/粘包
    这篇文章主要讲解了“go语言如何处理TCP拆包/粘包”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“go语言如何处理TCP拆包/粘包”吧!part 1最近在学习go自带的rpc,看完了一遍想着...
    99+
    2023-06-22
  • php的tcp粘包和拆包怎么实现
    今天小编给大家分享一下php的tcp粘包和拆包怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。tcp 长链接模式下,使...
    99+
    2023-07-04
  • Go语言中日期包(time包)的具体使用
    目录日期包常用函数定时器打印定时器终止定时器注意事项日期包 常用函数 time.Now(): 获取当前时间 package main import ( "fmt" "...
    99+
    2023-05-19
    Go 日期包 Go time
  • Golang通过包长协议处理TCP粘包的问题解决
    目录tcp粘包现象代码重现tcp粘包问题处理方法tcp粘包产生的原因这里就不说了,因为大家能搜索TCP粘包的处理方法,想必大概对TCP粘包有了一定了解,所以我们直接从处理思路开始讲起...
    99+
    2024-04-02
  • GO语言包管理工具go mod以及包详解
    目录1.GO中包的定义与介绍2. 包管理工具 go mod2.1 自定义包 (可以包含多个go文件)2.1.1 建立项目并go mod init初始化2.1.2 自定义一个包(文件夹...
    99+
    2024-04-02
  • Go语言包管理工具Godep的用法
    一、为什么要包管理 默认Go的第三方包都是放在Gopath的src目录下,而且这些包都没有版本号的概念,这样的可能会出现一些问题。 举个例子:当A同事将开发完程序之后,此时可能引用了...
    99+
    2024-04-02
  • Go语言递归函数的具体实现
    目录斐波那契数列数字阶乘多个函数组成递归很对编程语言都支持递归函数,Go语言也不例外,所谓递归函数指的是在函数内部调用函数自身的函数,从数学解题思路来说,递归就是把一个大问题拆分成多...
    99+
    2023-05-14
    Go语言递归函数
  • Go 语言打包工具:如何快速打包你的项目?
    在 Go 语言开发中,我们经常需要将我们的代码打包成可执行文件或者库文件。幸运的是,Go 语言提供了一些非常方便的打包工具来帮助我们完成这项工作。在本文中,我们将介绍 Go 语言中常用的打包工具,并演示如何使用这些工具来快速打包你的项目。...
    99+
    2023-08-16
    打包 load unix
  • 如何实现ASP重定向与自然语言处理的打包一体化?
    ASP重定向是一种常见的Web开发技术,可以将用户请求重定向到其他页面,从而实现各种功能。而自然语言处理(Natural Language Processing,NLP)则是一种人工智能技术,可以帮助计算机理解和处理自然语言。本文将介绍如何...
    99+
    2023-07-22
    重定向 自然语言处理 打包
  • GO语言创建钱包并遍历钱包(wallet)的实现代码
    基本知识 公钥加密算法使用的是成对的密钥:公钥和私钥,公钥可以公开,私钥不能被公开。比特币钱包实际上是一个密钥对,当你安装 一个钱包应用,或者是使用一个比特币客户端来生成一个新地址是...
    99+
    2024-04-02
  • Thinkphp语言包实现原理与实践
    我们知道,Thinkphp中支持语言包功能。ThinkPHP具备语言包定义、自动识别、动态定义语言参数的功能。 首先我们来说语言文件名称,该文件名称是受我们控制的,我们可以在底层配置文件conven...
    99+
    2024-02-27
  • 自然语言处理:Go Load打包的未来趋势?
    随着人工智能技术的不断发展,自然语言处理(NLP)成为了最受关注的领域之一。在过去的几年中,Go语言的流行度也越来越高,因为它具有高性能、并发性和易于编写的特点。在NLP中,Go语言也被广泛应用,尤其是在Go Load打包中。在本文中,我...
    99+
    2023-06-22
    load 打包 自然语言处理
  • 打包工具哪家强?Go语言中的打包技巧大揭秘!
    随着Go语言的流行,越来越多的开发者开始使用它来编写应用程序。在开发过程中,打包是一个必不可少的环节,它可以将我们的代码、依赖包以及其他资源打包成一个可执行文件或者库。但是在Go语言中,有很多种打包工具可供选择,如何选择一个适合自己的工具...
    99+
    2023-10-14
    异步编程 编程算法 打包
  • 汉语言处理包Hanlp的使用
    本来想通过python调用Java实现Hanlp的使用,参考文章:http://t.cn/RUrIF7z ##########python可以用easy_install安装一些软件##########...
    99+
    2024-04-02
  • GO语言中HTTP打包文件的工具推荐!
    随着互联网技术的不断发展,Web应用程序的需求不断增加,如何提高Web应用程序的性能和效率成为了程序员们的重要任务。在这个过程中,HTTP打包文件工具的使用变得越来越重要。本文将介绍GO语言中HTTP打包文件的工具推荐,并结合演示代码详细...
    99+
    2023-06-24
    http 打包 文件
  • Go语言TCP从原理到代码实现详解
    目录引言TCP介绍特点图解代码实现1. 连接1.1 服务端1.2 客户端2. 通信2.1 服务端2.2 客户端3. 回复3.1 服务端3.2 客户端引言 基于net包的小应用 完整代...
    99+
    2024-04-02
  • Go语言如何处理大数据日志打包?
    在当今的互联网时代,每个人都会产生大量的数据日志。因为这些数据日志往往是以文本形式存储,所以会占用大量的磁盘空间。为了解决这个问题,我们需要对这些数据日志进行打包,以减少磁盘空间的占用。本文将介绍如何使用Go语言处理大数据日志打包的问题。...
    99+
    2023-09-01
    大数据 日志 打包
  • Go语言中的闭包实例分析
    这篇文章主要介绍“Go语言中的闭包实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go语言中的闭包实例分析”文章能帮助大家解决问题。一、函数的变量作用域和可见性全局变量在main函数执行之前初...
    99+
    2023-07-02
  • React组件二次包装的具体实现
    目录1. 类型声明2. 默认属性3. 自定义属性与属性透传原生组件是对公共场景的抽象,若要契合实际业务往往需要对其进行二次包装。对组件进行二次包装一般需要进行包括不限于以下的步骤: ...
    99+
    2024-04-02
  • Go语言包管理实践:依赖性探讨
    go 语言包管理采用 go 模块系统,将依赖关系组织成树形结构,自动解析和下载依赖项。实战中,通过在 go.mod 文件中指定模块路径和版本号,即可引入第三方库。go 模块支持精确指定依...
    99+
    2024-04-03
    go语言 包管理
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作