Go 处理粘包拆包

news/2024/5/17 15:14:08 标签: golang, TCP, 粘包拆包

Go 处理粘包拆包

1. 什么是粘包?

发送方发送的若干数据到接受放接受时粘成了一个包。接受方有一个缓冲区,在缓冲区中多条数据连在了一起。

2. 粘包发生在哪个协议中?

只有TCP有粘包现象,UDP没有

3. 为什么UDP没有粘包想象?

因为UDP无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送(也就没有Nagle算法之说了) ,他直接是一端发送什么数据,直接就发出去了 ,既然他不会对数据合并,每一个数据包都是完整的(数据+UDP头+IP头等等发一次数据封装一次)也就没有粘包一说

TCP_20">4. TCP为什么会出现粘包想象

TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。
收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的

TCP_25">5. TCP出现粘包、拆包的几种情况?

  • 发送端写入的数据大于接收端套接字(socket)缓冲区的大小,会发生拆包
  • 发送端写入的数据小于接收端套接字(socket)缓冲区的大小,网络会将多次写入的数据同时发送出去,会发生粘包
  • 进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候将发生拆包
  • 接收端未能及时读取套接字(socket)缓冲区中的数据,也会发生粘包

6. 如何处理粘包、拆包

  • 使用带消息头的协议,头部写入包长度,然后再读取包内容
  • 设置定长消息,每次读取定长的消息内容,长度不够时空位补全(固定字段)
  • 设置消息边界,服务端从网络流中按消息边界分离出消息内容。比如\n
  • Json、protobuf协议框架

7. 使用自定义消息格式处理粘包和拆包的问题

  1. 首先会写入一个自定义的消息头
binary.Write(bytesBuffer, binary.BigEndian, []byte(MsgHeader))
  1. 写入消息内容的长度
clen := int32(len([]byte(content)))
binary.Write(bytesBuffer, binary.BigEndian, clen)
  1. 写入消息
binary.Write(bytesBuffer, binary.BigEndian, []byte(content))
  1. 拆包 先读自定义的消息头,
io.ReadFull(bytesBuffer, headBuf)
  1. 在读指定长度的消息
io.ReadFull(bytesBuffer, lbuf)
io.ReadFull(bytesBuffer, body)

完整代码地址: https://github.com/jeffcail/tcp-unpack


http://www.niftyadmin.cn/n/3549.html

相关文章

C++ 宏定义+模板 实现 判断类名中是否存在某个函数名称

链接:(1条消息) C怎么判断一个类存在指定的函数名的函数_写了程序换酒钱的博客-CSDN博客 1.使用宏来包含模版,这里主要考虑到模版不能成为虚函数,所以这里只是单纯的复制能力。即宏定义中可以定义模板,但不能直接使用当前定义的。…

Docker创建FTP服务器

Docker创建FTP服务器 一.创建命令如下 docker run -d -p 20:20 -p 21:21 -p 21100-21110:21100-21110 -v /opt/vsftpd/file:/home/vsftpd -e FTP_USERlihaozhe -e FTP_PASSlihaozhe -e PASV_MIN_PORT21100 -e PASV_MAX_PORT21110 -e PASV_ADDRESS192.168.95.21 -e PASV_ENAB…

05 css选择器以及优先级?说盒子模型的了解?知道BFC?三栏布局的几种方式? CSS的几种预处理器?有几种让盒子水平垂直居中的方法?

1 你真的掌握样式优先级和选择器优先级吗? 考点:选择器以及优先级 样式优先级 最近的祖先样式比其他祖先样式优先级高 "直接样式"比"祖先样式"优先级高 选择器优先级 内联样式 > id选择器 > 类选择器 属性选择器[titlec] …

【python】内置库函数大集合 ❢ 这不得点赞收藏一波~

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ Python内置库这么多,要不要全部都学,记不住啊 那怎么办呢? 俗话说的好:好记性不如烂笔头 就算脑子再好使,但它毕竟存储有限&#xff0…

C++入门学习3-指针与字符数组,函数,指针数组

c入门学习3char型指针的使用p*p*p与p与[整型指针指向整型数组]的区别指针与函数的使用指向函数的指针空指针调用函数从函数中返回指针一维数组和二维数组的类比CHAR型指针数组关于&achar型指针的使用 char型指针可以直接指向一个字符串,如下 char s[]{a,b,c};…

Java二叉搜索树

1.二叉搜索树的概念 二叉搜索树是一颗特殊的二叉树: 它的左子树的所有节点的值,均小于根节点; 它的右子树的所有节点的值,均大于根节点. 二叉搜索树的中序遍历总是有序的!!! 二叉搜索树查找数据的时间复杂度为 O(logN) ,当树为单分支树时,时间复杂度达到 O(N) . 2.二叉搜…

项目计划不要拖,要赶紧排

案例 业主:这个项目很急,赶紧干活吧,明天就安排人来干活。 于是,项目经理问公司要来资源,第二天就投入到项目里。 公司只有一个项目,这样搞,项目能顺利实施,业主满意,公司老板感觉这种方法不错哦。 当公司项目越来越多了,员工也越来越多的时候,混乱的场面就出现…

快速上手分布式版本控制工具Git

文章目录前言一.分布式版本控制工具Git二.Git基本指令1.查看用户信息2.获取Git仓库3.工作区、暂存区、版本库4.查看文件修改状态(status)5.添加工作区到暂存区(add)6.提交暂存区到本地仓库(commit)7.查看日…