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)

相关推荐

  • 大数据中AWK命令的示例分析

    技术大数据中AWK命令的示例分析这篇文章将为大家详细讲解有关大数据中AWK命令的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。对于下面的nginx日志access.log,用脚

    攻略 2021年11月20日
  • Java循环和数组练习题有哪些

    技术Java循环和数组练习题有哪些这篇文章主要介绍“Java循环和数组练习题有哪些”,在日常操作中,相信很多人在Java循环和数组练习题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

    攻略 2021年11月21日
  • 数据库的语句应该如何优化

    技术数据库的语句应该如何优化这篇文章主要介绍了数据库的语句应该如何优化,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  在MySQL数据库怎么加快查询速度

    攻略 2021年10月26日
  • C/C++编译器QStudio怎么使用

    技术C/C++编译器QStudio怎么使用本篇内容介绍了“C/C++编译器QStudio怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔

    攻略 2021年11月30日
  • 二分图

    技术二分图 二分图二分图
    定义
    二分图,又称二部图,英文名叫 Bipartite graph。
    二分图是什么节点由两个集合组成,且两个集合内部没有边的图。
    换言之,存在一种方案,将节点划分成满足以上性质

    礼包 2021年11月24日
  • Django组件-cookie与session

    技术Django组件-cookie与session Django组件-cookie与sessionDjango组件-cookie与session
    会话跟踪技术
    1 什么是会话跟踪技术
    我们需要先了解

    礼包 2021年12月13日