Tcp的粘包和半包问题及解决方案

news/2025/1/11 20:59:42/

目录

粘包:

半包:

应用进程如何解读字节流?如何解决粘包和半包问题?

①:固定长度

②:分隔符

③:固定长度字段存储内容的长度信息


粘包:

一次接收到多个消息,粘包

应用进程无法从一个粘包中解析出数据

出现粘包的原因:

①:发送方每次写入数据<内核缓冲区大小;导致多个小的数据包一次性放到一个缓冲区中一起发送了,接收端接收到数据就对导致粘包。

②:接收方读取内核缓冲区不够及时。Tcp接收数据的三个队列并不是实时的,有可能会延时,可能会导致读到多个消息,粘包了。 

半包:

 一个消息分多次接收,半包

应用进程无法从一个半包中解析出数据

出现半包的原因:

①:发送方写入数据>内核缓冲区大小;

②:发送方数据大小大于MTU,必须拆包。

        应用进程是无法从一个粘包、半包中解析出数据的,根本原因是:Tcp是面向字节的,消息无边界的。

应用进程如何解读字节流?如何解决粘包和半包问题?

找出消息的边界

①:固定长度

简单、但是浪费空间,不推荐。

(比如规定每10个字节表示一个消息,但是客户端发送的一个消息里只有1个字节那么剩下的字节就是浪费的,需要补空或者补0)

②:分隔符

简单,空间也不浪费,推荐使用
缺点:数据内容本身出现分隔符时,需要转义,所以需要扫描内容

典型的例子就是HTTP报文:

③:固定长度字段存储内容的长度信息

 接收端先解析固定字段,获取长度,然后根据长度读取数据内容。

可以精确定位数据内容,内容不需要转义,推荐

缺点:数据内容长度有限制,需要提前知道可能的最长的消息的字节数
 


http://www.ppmy.cn/news/1003845.html

相关文章

【如何使用cv::erode()函数对图像进行腐蚀操作】

文章目录 `cv::erode()`函数主要用途`cv::erode()`函数的参数卷积核cv::erode()函数主要用途 cv::erode()函数主要用于进行图像的腐蚀操作。这是一种图像处理技术,通常用于消除图像中的噪声、分离两个连接在一起的物体、或者使物体的边界变得更加明显。 腐蚀操作的基本思想是…

Java基础面试题1

Java基础面试题 一、面向对象和集合专题 1. 面向对象和面向过程的区别 面向过程&#xff1a;是分析解决问题的步骤&#xff0c;然后用函数把这些步骤一步一步地实现&#xff0c;然后在使用的时候一一调用则可。性能较高&#xff0c;所以单片机、嵌入式开发等一般采用面向过程…

解决springcloud项目添加多数据源新模块时启动正常调用却报没有设置默认数据源的问题

在原有springcloud项目新添加了一个多数据源模块&#xff0c;结果启动正常却无法调用方法&#xff0c;每次调用都报错 ”没有设置默认数据源“&#xff0c;最后找了很多解决办法都无效&#xff0c;最终还是把配置中心的properties删掉了&#xff0c;改成了直接在模块resource中…

C++ 数组

数组是具有一定顺序关系的若干对象的集合体&#xff0c;组成数组的对象称为该数组的元素。 数组元素用数组名与带方括号的下标表示&#xff0c;同一数组的各个元素具有相同的类型。数组可以由除void型以外的任何一种类型构成&#xff0c;构成数组的类型和数组之间的关系&#x…

Vue组件化开发--公共组件的封装

在Vue中&#xff0c;组件是构建用户界面的基本单位。封装公共组件是一种良好的实践&#xff0c;可以提高代码的可复用性和可维护性。下面是一个示例&#xff0c;演示了如何封装一个公共的按钮组件。 首先&#xff0c;创建一个名为Button.vue的Vue组件文件。这个组件将封装一个…

MybatisPlus实战笔记

概述 Mybatis支持定制化SQL、存储过程以及高级映射&#xff0c;避免几乎所有的 JDBC 代码和手动设置参数以及获取结果集。可以使用简单的 XML 或注解来配置和映射原生信息&#xff0c;将接口和Java的POJO映射成数据库中的记录。 缺点&#xff1a; SQL工作量很大&#xff0c;尤…

ZigBee - 小记

文章目录 ZigBee&#xff0c;也称紫蜂&#xff0c;是一种低速短距离传输的无线网路协定&#xff0c;底层是采用IEEE 802.15.4标准规范的媒体存取层与实体层。 主要特色有低速、低耗电、低成本、支援大量网路节点、支援多种网路拓扑、低复杂度、可靠、安全。 维基百科 : ZigBee …

python+opencv实现显示摄像头,截取相关图片,录取相关视频

实时显示摄像头图像 按下空格键&#xff0c;截取图片 按下tab键&#xff0c;开始录制摄像内容&#xff0c;再次按下&#xff0c;结束录制 按下Esc键&#xff0c;关闭窗口 import cv2 import numpy#第几章图片 img_count0InitVideoFalse #第几个视频 video_count0 video_flagFa…