当前位置: 首页 > news >正文

Qt中对TCP粘包的处理

当时用TCP协议传输数据时,经常出现粘包的现象
当服务器向客户端发送数据之后,客户端还没有接收数据的时候,这段时间数据在什么地方?
1、服务器?服务器已经发出数据了
2、网线?数据应该在内存,怎么会在网线里面,又没有内存
3、客户端?是的,这个时候数据已经到达客户端了,只不过被保存在客户端的缓存中了(内核缓冲区),客户端只有在read的时候才能读出数据
场景:服务器每次给客户端发出一条数据,但是每次发送数据的量是不一样的,这时要求客户端把服务器发过来的数据依次接收到本地并且进行对应的解析,如果客户端一次发出10个字节,那么客户端也一次读出10个字节,如果多读了,那么就把下一条数据读出来了,此时解析数据会是错误的,这就是TCP粘包

处理办法:发送端在每一个数据包前面加上包头,包头中加入数据长度
接收端接收到后的处理:首先包头的大小是固定的,一般就是一个long或者int类型,所以我们根据这个long或者int类型求出一个固定大小,8字节(long)或者4字节(int),所以在读数据包的时候直接根据这个类型先去读8字节或者4字节,这样就可以读出数据包的长度,然后根据这个长度去读后边的这个数据块
比如此次接收到的长度为100,那么就向后读取100个字节的数据,就是此次的一个包,哪怕此时缓冲区有1000个字节数据,只读这100个字节就能获取一个完整的包,剩余的900个字节就需要下一次去处理,下次处理的时候还是先读包头,读出数据包的一个长度,然后根据这个长度去读取相应的数据,这样一次一次读取就可以一点一点把数据拆分出来了

例:这里以Qt编写的基于opencv的人脸识别的服务器和客户端为例,客户端发送拍下的人脸发送到服务器进行识别,要求传输一帧完整的人脸数据,这就有可能粘包,可能同时发送两个人脸向服务器,此时就需要处理粘包
首先客户端发送图片数据

//把Mat数据转化为QbyteArray, --》编码成jpg格式
std::vector<uchar> buf;
cv::imencode(".jpg",srcImage,buf);   //这就是将拍摄的原始的图像转为jpg然后将数据放到buf中
QByteArray byte((const char*)buf.data(),buf.size()); //数据格式转为QByteArray 
//准备发送
quint64 backsize = byte.size();    //获取数据的长度,这里可以看到backsize是quint64型变量,占8个字节
QByteArray sendData;
QDataStream stream(&sendData,QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_14);
//将数据放入码流,首先放入数据的长度backsize,quint64为8字节的长度,后面就是数据
stream<<backsize<<byte;  
//发送
msocket.write(sendData);  //将数据包发送

服务器接收图片数据

static quint64 bsize = 0;  //全局变量QDataStream stream(msocket); //把套接字绑定到数据流
stream.setVersion(QDataStream::Qt_5_14);if(bsize == 0){//查看目前TCP的内存缓冲区的数据长度是否能达到bsize所占的字节数,这里应该是8字节if( msocket->bytesAvailable() < (qint64)sizeof(bsize) ) return ;//说明数据长度够8个字节,然后就可以获取采集数据的长度stream>>bsize;
}//获取目前缓存中剩余数据的长度,小于刚才获取的8字节的数据长度说明数据还没有发送完成,返回继续等待
if(msocket->bytesAvailable() < bsize)
{return ;  //此时bsize没有清空,下次还会来这里检查获取的数据长度是否大于或等于bsize
}
QByteArray data;
stream>>data;
bsize = 0;   // 将bsize设为0,说明处理完了一包数据 
if(data.size() == 0)//没有读取到数据
{return;
}//显示图片
QPixmap mmp;
mmp.loadFromData(data,"jpg");
mmp = mmp.scaled(ui->picLb->size());
ui->picLb->setPixmap(mmp);

相关文章:

Qt中对TCP粘包的处理

当时用TCP协议传输数据时&#xff0c;经常出现粘包的现象 当服务器向客户端发送数据之后&#xff0c;客户端还没有接收数据的时候&#xff0c;这段时间数据在什么地方&#xff1f; 1、服务器&#xff1f;服务器已经发出数据了 2、网线&#xff1f;数据应该在内存&#xff0c;怎…...

贪心-单调递增的数字

当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9示例 2: 输入: n 1234 输出: 1234示例 3: 输入…...

你真的会用搜索引擎吗?

作为一名在校大学生&#xff0c;对于搜索资料这一件事深有体会&#xff0c;特别是在期末考试突击的时候&#xff0c;如何利用搜索引擎&#xff0c;快速找到自己想要的知识&#xff0c;快速理解这个知识点&#xff0c;想必是每位大学生的必备技能了。 我们在学习一个知识点的过…...

KDCJ-20kV冲击耐压测试仪

一、产品简介 KDCJ-20kV冲击耐压测试仪是电力设备高压试验的基本项目之一&#xff0c;电力设备在设计、制造及修缮之后都要求进行冲击试验以验证或检验。因此&#xff0c;冲击电压试验设备有着广泛的应用&#xff0c;在工厂、研究机构及大专院校的高压试验室中都可以看到不同规…...

【Mybatis源码分析】TypeAliasRegistry源码分析

TypeAliasRegistry源码分析一、引入类型别名二、typeAlias 的三种配置方式三、TypeAliasRegistry源码分析三种配置方式源码解析校验过程Mybatis默认的别名配置四、总结一、引入类型别名 当配置 XML 文件&#xff0c;需要指明Java类型时&#xff0c;类型别名可替代Java类型的全…...

节点高负载

如何判断节点高负载? 可以通过 top 或 uptime 来确定 load 大小,如果 load 小于 CPU 数量,属于低负载,如果大于 CPU 数量 2~3 倍,就比较高了,当然也看业务敏感程度,不太敏感的大于 4 倍算高负载。 排查思路 观察监控:通常不是因为内核 bug 导致的高负载,在卡死之前…...

动态规划(一) part1

T1:一个数组 中的最长 升序 子序列 的长度 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组…...

Ubuntu显卡报错:Failed to initialize NVML Driver/library version mismatch

问题描述 输入指令nvidia-smi的时候&#xff0c;出现如下&#xff1a; Failed to initialize NVML: Driver/library version mismatch看起来好像是版本不匹配&#xff0c;在网上查了很多都没有解决问题&#xff0c;重启也不行&#xff0c;结果证明最好的办法是重新安装cuda。…...

JAVA企业电子采购系统源码:采购过程更规范,更透明

满足采购业务全程数字化&#xff0c; 实现供应商管理、采购需求、全网寻源、全网比价、电子招 投标、合同订单执行的全过程管理。 电子招标采购&#xff0c;是指在网上寻源和采购产品和服务的过程。对于企业和企业主来说&#xff0c;这是个既省钱又能提高供应链效率的有效方法…...

5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世

MWC2023大会召开在即&#xff0c;5GAdvanced产业再添重磅消息&#xff01;2月15日&#xff0c;高通宣布推出全球首个5GAdvanced-ready基带芯片——骁龙X755G调制解调器及射频系统&#xff0c;支持毫米波和Sub-6GHz频段&#xff0c;带来网络覆盖、时延、能效和移动性等全方位的提…...

基于B站王阿华的视频——为什么当下自媒体都在制造焦虑以及如何摆脱

观后笔记2.0——一些深入的思考 1.情绪大约在两千万年前&#xff0c;哺乳脑统治期间诞生。 2.情绪分为积极情绪和负面情绪。决定某种情绪的出现取决于安全感等级。 自媒体制造负面情绪&#xff0c;想尽办法挑起情绪&#xff0c;吸引流量 安全感充足时&#xff0c;由积极情绪…...

一、Docker介绍:

Docker官方网站&#xff1a;https://www.docker.com/ Docker容器技术是虚拟化技术的一个分支&#xff0c;虚拟化技术一般分为两种&#xff1a; 硬件级虚拟化&#xff08;hardware-level-virtualization&#xff09; &#xff1a;是运行在硬件之上的虚拟化技术&#xff0c;它的核…...

Vue进阶(一篇进入Vue3的世界)

文章目录一、初识Vue3二、Vue3新语法糖setup三、响应式数据函数3.1 ref函数3.2 reactive函数3.3 ref和reactive函数的异同四、Vue3的响应式原理五、语法更新5.1 Vue3使用computed计算属性5.2 Vue3使用watch监视属性的注意点5.2.1 监视ref对象5.2.2 监视reactive对象5.2.3 监视嵌…...

功能测试的分类,分别有什么作用?

目录 前言 一、链接测试 二、表单测试 三、搜索测试 四、删除测试 五、cookies/session测试 六、数据库测试 七、峰值测试/容量测试 八、相容性测试/安全测试 前言 功能测试主要包括链接测试、表单测试、搜索测试、删除测试、cookies、session测试、数据库测试等部分…...

51单片机学习笔记_14 红外遥控

红外传感器 遥控器通过红外 LED 发送调制后的信号&#xff0c;开发板上的红外接收模块接收遥控器的红外线。 单工异步&#xff0c;940nm 波长&#xff08;还有一种 250nm 的N&#xff0c;可见光&#xff09;&#xff0c;EC 通信标准。 38KHz&#xff1a;红外线频率。 IN&…...

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(五)

此文章为【我是土堆 - Pytorch教程】 知识点 学习总结笔记&#xff08;五&#xff09;包括&#xff1a;完整的模型训练套路&#xff08;一&#xff09;、完整的模型训练套路&#xff08;二&#xff09;、完整的模型训练套路&#xff08;三&#xff09;、利用GPU训练&#xff08…...

JUC篇:CopyOnWriteArrayList的应用与原理

系列文章目录 JUC篇&#xff1a;volatile可见性的实现原理 JUC篇&#xff1a;synchronized的应用和实现原理 JUC篇&#xff1a;用Java实现一个简单的线程池 JUC篇&#xff1a;java中的线程池 JUC篇&#xff1a;ThreadLocal的应用与原理 JUC篇&#xff1a;Java中的并发工具类 文…...

【总结】爬虫1-requests

爬虫1-requests 1. requests的基本用法 requests需要提前导入&#xff0c;才能使用 1.1 请求网络数据&#xff1a;requests.get(请求地址) response requests.get(https://cd.zu.ke.com/zufang)1.2 设置解码方法&#xff08;罗马的是需要设置 - 一定要在获取请求结果之前设…...

基于springboot实现学生综合成绩测评系统【源码】分享

基于springboot实现学生综合成绩测评系统演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包…...

uniapp初体验———uView组件库的使用与钉钉小程序的运行

这周学长给了我一个校企合作的项目&#xff0c;要求是用uniapp开发&#xff0c;最终打包成钉钉小程序&#xff0c;不过我并不会uniapp&#xff0c;也是学了一段时间&#xff0c;开始写项目&#xff0c;中间也遇到过很多问题&#xff0c;比如开发者工具还有如何运行到开发者工具…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...