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

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

本文主要讲解“如何用go语言处理TCP拆包/粘包”。本文的解释简单明了,易学易懂。现在,请跟随边肖的思路,一起学习学习《如何处理围棋语言中的TCP拆包/卡壳》!

00-1010最近研究了go附带的rpc。看了一遍,我以为我会实现一个编解码器,就是自定义消息的序列化和反序列化。消息的序列化和反序列化涉及两个步骤:

1.从网络中读取数据并将数据写入网络;

2.根据获取的二进制数据反序列化,将现有对象序列化为二进制数据。在这个过程中,我们需要处理TCP的拆包和粘贴。

TCP的拆包/上胶也是网络编程中比较基础的问题,具体的含义和解决方法就不详细描述了。虽然实现应用层逻辑的程序员可能根本不需要关心这个,但是作为中间件的开发,出于学习go语言的目的,还是有点练习的。

part 1

TCP拆包卡顿解决方案:读取数据时,将读取的二进制数据划分到正确的位置。这里直接使用head body方法,即发送数据时,先将整个数据的大小追加到数据中,如下所示:

大小(2字节)|正文(大小字节)

这里,以数据包的大小为头。

注意:在这里给出的例子中,大小占2字节;大小占用的具体字节数可以根据实际情况确定。

part 2

服务器实施:

funcdoConn(connet。conn){ 0

var(

buffer=bytes . new buffer(make([]byte,0,buf _ size))//buffer用于缓冲读取的数据。

ReadBytes=make ([] byte,buf _ size)//Read bytes用于接收每次读取的数据,并在每次读取后将读取的字节添加到缓冲区中。

I sead=true////用于标识当前状态:是尺寸部分还是身体部分正在处理中。

BodyLen=0//表示正文的长度。

)

对于{ 0

//先读数据

读取字节数,错误:=连接。读取(读取字节)

伊弗。=零

日志。致命的

返回

}

buffer . write(read bytes[0: read bytenum])//将读取的数据放入缓冲区。

//然后处理数据。

对于{ 0

ifisHea

d {
                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拆包/粘包这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/140963.html

(0)

相关推荐

  • 猪宝宝小名,我想帮宝宝取个好听的小名

    技术猪宝宝小名,我想帮宝宝取个好听的小名姓名,记录着宗族血统的烙印,凝聚着父母对孩子的深情厚义,隐喻着不同的理想追求和目标;姓名,传承了人的情、意、志;姓名,蕴含了人的精、气、神猪宝宝小名。人的姓名不只是一个人体符号,而

    生活 2021年10月30日
  • 最新单机游戏排行榜,十大耐玩手机单机游戏有哪些

    技术最新单机游戏排行榜,十大耐玩手机单机游戏有哪些我觉得比较好玩的十个手机单机游戏有最新单机游戏排行榜:《地狱边境》、《刺客信条》、《狂爆之翼》、《阿尔托的冒险》、《滑雪大冒险》、《方舟》、《使命召唤(手游版)》、《我的

    生活 2021年10月26日
  • redis中RedissonLock如何实现等待锁

    技术redis中RedissonLock如何实现等待锁今天就跟大家聊聊有关redis中RedissonLock如何实现等待锁,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有

    攻略 2021年11月11日
  • cd的ifpi码(ci指标的使用方法)

    技术怎么实施弹性CI/CD本篇文章给大家分享的是有关怎么实施弹性CI/CD,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。数字化转型正在迅速地改善客户体验和运

    攻略 2021年12月21日
  • 忽视数据中心物理基础设施的现代化将产生的问题有哪些

    技术忽视数据中心物理基础设施的现代化将产生的问题有哪些这篇文章主要讲解了“忽视数据中心物理基础设施的现代化将产生的问题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“

    攻略 2021年10月22日
  • ADO.NET sql server存储过程怎么调用

    技术ADO.NET sql server存储过程怎么调用这篇文章主要介绍“ADO.NET sql server存储过程怎么调用”,在日常操作中,相信很多人在ADO.NET sql server存储过程怎么调用问题上存在疑

    攻略 2021年12月3日