1、如何解决粘包问题?

在设计网络协议时,可能会存在粘包、丢包或者包乱序问题,但TCP协议时可靠性协议,大多数情况不存在丢包和乱序问题,但UDP协议如果不能接受少量丢包,就必须自己设计有序和可靠性传输机制(比如:RTP协议、RUDP协议,)。因此,只存在如何解决粘包的问题。

TCP 协议是流式数据格式。解决问题的思路还是想办法从收到的数据中把包与包的边界给区分出来。那么如何区分呢?目前主要有三种方法:

  • 固定包长的数据包
  • 以指定字符(串)为包的结束标志
  • 包头 + 包体格式

2、如何处理解包问题?

包头 + 包体 这种格式的数据包的捷豹处理的流程如下:

假如 包头格式如下:

//强制一字节对齐
#pragma pack(push, 1)
//协议头
struct msg_header
{   int32_t  bodysize;         //包体大小
};
#pragma pack(pop)

代码流程如下:

//包最大字节数限制为10M
#define MAX_PACKAGE_SIZE    10 * 1024 * 1024void ChatSession::OnRead(const std::shared_ptr<TcpConnection>& conn, Buffer* pBuffer, Timestamp receivTime)
{while (true){//不够一个包头大小if (pBuffer->readableBytes() < (size_t)sizeof(msg_header)){//LOGI << "buffer is not enough for a package header, pBuffer->readableBytes()=" << pBuffer->readableBytes() << ", sizeof(msg_header)=" << sizeof(msg_header);return;}//取包头信息msg_header header;memcpy(&header, pBuffer->peek(), sizeof(msg_header));//包头有错误,立即关闭连接if (header.bodysize <= 0 || header.bodysize > MAX_PACKAGE_SIZE){//客户端发非法数据包,服务器主动关闭之LOGE("Illegal package, bodysize: %lld, close TcpConnection, client: %s", header.bodysize, conn->peerAddress().toIpPort().c_str());conn->forceClose();return;}//收到的数据不够一个完整的包if (pBuffer->readableBytes() < (size_t)header.bodysize + sizeof(msg_header))return;pBuffer->retrieve(sizeof(msg_header));//inbuf用来存放当前要处理的包std::string inbuf;inbuf.append(pBuffer->peek(), header.bodysize);pBuffer->retrieve(header.bodysize);//解包和业务处理if (!Process(conn, inbuf.c_str(), inbuf.length())){//客户端发非法数据包,服务器主动关闭之LOGE("Process package error, close TcpConnection, client: %s", conn->peerAddress().toIpPort().c_str());conn->forceClose();return;}}// end while-loop
}

pBuffer 这里是一个自定义的接收缓冲区,这里的代码,已经将收到的数据放入了这个缓冲区,所以判断当前已收取的字节数目只需要使用这个对象的相应方法即可,需要注意如下问题:

  • 取包头之前:需判断缓冲区 pBuffer 中的可读数据大小是否超过一个报文长度,否则直接退出。
  • 取包头之后:需判断报文体大小是否超过自己规定最大值,避免发超大型数据耗尽内存。
  • 多帧处理:使用while一直处理报文,直到缓冲区数据不足一帧报文结束。

网络粘包解包问题杂谈相关推荐

  1. python3 抓包 解包_Python结构包,解包

    python3 抓包 解包 Python struct module is capable of performing the conversions between the Python value ...

  2. Java版ISO8583报文组包/解包

    文章目录 一.8583协议简介 二.位图规则 三.8583格式报文参考 四.组包/解包思路 五.相关代码 一.8583协议简介   8583协议是基于ISO8583报文国际标准的包格式的通讯协议,85 ...

  3. C语言字符串的组包解包

    组包解包 sprintf组包 sscanf解包 sscanf的高级用法1:使用%*s %*d 跳过提取的内容(不要提取的内容) sscanf的高级用法2:使用%[n]s %[n]d 提取指定宽度n的字 ...

  4. 【各个模块间数据交互通讯及接口定义】串口通讯--压包解包,解析数据帧的方法

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 (1)ROS的分布式通信 (2)串口通讯--压包解包,解析数据帧的方 ...

  5. 网络传输粘包解包处理

    有时候发送的数据过长,接收的时候只接收了一部分,会出现错误.这里以客户端接收服务端消息为例,讲解一种解包的方法,作为备忘(总是忘没办法) 1.客户端有一段缓冲区char m_szAnalysisBuf ...

  6. python unpacking_python packing unpacking 组包解包

    packing 组包,函数使用 [*] (for tuples)[元组], & [**](for dict) [ 字典]来接受可迭代的参数 unpacking 解包 ,函数内部定义多个参数(可 ...

  7. 安卓rom包解包linux,Android rom解包打包工具

    eMMC主要是针对手机和平板电脑等产品的内嵌式存储器,由于其在封装中集成了一个控制器,且提供标准接口并管理闪存等优势,越来越受到Android手机厂商的青睐,以eMMC为存储设备的android手机, ...

  8. 安卓rom包解包linux,[ROM开发]解包打包ROM详细教程 2017.9.8更新安卓7.0

    解包和打包system.img 直接挂载mount system.img /mnt/rom 修改后打包 file_contexts放在当前目录 即打包的img所在目录make_ext4fs -S ./ ...

  9. 微信小程序(.wxapkg)源码包解包的方法

    首先下载微信小程序的解包工具:微信小程序(.wxapkg)文件解包工具 下载地址: 工具下载 cmd切换到源码的存放目录,直接将工具和源码放一个文件夹吧,执行: java -jar unweapp-0 ...

最新文章

  1. 参加完Python培训后有哪些就业方向
  2. mysql删除表中的唯一索引吗_Mysql 使用sql删除同表中重复数据并加唯一索引
  3. 华为网络技术培训笔记之常用网络工具(二)
  4. Hyper-V群集之使用指南
  5. eclipse性能优化
  6. NMF和SVD在推荐系统中的应用(实战)
  7. WP7上Metro风格的程序栏图标汇总
  8. Hystrix解决雪崩问题的两种手段
  9. ElasticSearch—基本概念
  10. 本地音频播放,使用AVFoundation.framework中的AVAudioPlayer来实现
  11. linux 运行jar main,Maven打包生成jar包并在linux下启动main方法
  12. 计算机科学与技术做什么实验,计算机科学与技术专业实验教学大纲
  13. 计算Fibonacci数列第n项的第8种方法(数学推导与Python实现)
  14. BZOJ1345 [Baltic2007]序列问题Sequence
  15. 【字典树】添加和查找单词
  16. 解决PyCharm调试查看变量时一直显示collecting data并报错Timeout waiting for response且看不到任何内容
  17. asp.net 读写 XML 小结
  18. appassembler-maven-plugin插件打包本地依赖的jar
  19. Java实现阶乘的计算(四种方法)
  20. windows下 PHP 安装

热门文章

  1. 例29:哥德巴赫猜想
  2. 【数据结构笔记11】二叉搜索树,动态查找,删除操作
  3. keytool 错误 java.io.IOException: incorrect AVA format
  4. Xamarin开发Android---提示、跳转、传递数值 (学习总结)
  5. EDA实验课课程笔记(五)——NC-verilog的介绍与使用(一)
  6. 大一java怎么学好_是否应该学习第二门语言,学那个比较合适。
  7. 安卓nfs网络文件服务器,Linux网络文件服务器 NFS
  8. 素数筛法求素数(线性时间)
  9. 总结必须学习的10项.NET技术
  10. 调用存储过程时报错:Illegal mix of collations