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)

相关推荐

  • Java如何访问SSL enabled DB2 Database

    技术Java如何访问SSL enabled DB2 Database这篇文章给大家分享的是有关Java如何访问SSL enabled DB2 Database的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编

    攻略 2021年11月24日
  • dbms_xplan.display_cursor包与高级所有统计上次查看绑定区别是什么

    技术dbms_xplan.display_cursor包与ADVANCED ALLSTATS LAST PEEKED_BINDS区别是什么dbms_xplan.display_cursor包与ADVANCED ALLST

    攻略 2021年12月24日
  • elasticsearch推荐书籍(elasticsearch统计有多少字数)

    技术将唐诗三百首写入 Elasticsearch 会发生什么本篇文章给大家分享的是有关将唐诗三百首写入 Elasticsearch 会发生什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,

    攻略 2021年12月16日
  • 田鸡的做法,水煮田鸡的正宗做法王刚

    技术田鸡的做法,水煮田鸡的正宗做法王刚1田鸡买的时候让杀好,砍成块,头跟爪子不要,清洗干净,用醋田鸡的做法、生抽、料酒、姜丝、蒜头腌制一会
    2
    花菜撕成小朵,仔细清洗沥干备用(也可以换成白菜,豆芽,黄瓜,木耳)
    3
    花椒

    生活 2021年10月28日
  • C++中怎么使用工厂函数

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

    攻略 2021年11月29日
  • 抖音刷粉网址,人工刷粉丝会被封号吗?

    技术抖音刷粉网址,人工刷粉丝会被封号吗?抖音是当下非常受欢迎的一个社交软件,这样一个宣传度广的社交平台自然会吸引很多商家入驻广告,也就会衍生出很多的带货网红。成长一个做宣传推广的带货网红,前提是要有人气要有粉丝关注才能有

    测评 2021年11月11日