QT 处理TCP粘包问题
QT处理TCP粘包问题
处理粘包的方式是在消息头部加上消息总长度。
采用该格式:
消息总长度len(4字节)+命令字commandId(4字节)+消息msg
思路是用一个buffer,每次有消息就读完,然后判断buffer长度,收到四字节长度len后,根据len收消息,当buffer.size()>=len,这时已经收到一个完整的包就可以处理了,处理完后就将buffer前len个字节删除掉,如此反复。
//socket有数据到来就读
connect(m_socket, SIGNAL(readyRead()), this, SLOT(ReadData()));void Foo::ReadData()
{m_buf->append(m_socket->readAll()); //buf是QByteArray指针,可以在类内定义int ret = 1;while (ret > 0){ret = TryDecode(*m_buf);if (ret < 0)qDebug() << "TryDecode() failed";else if (ret > 0)m_buf->remove(0, ret);}
}int Foo::TryDecode(QByteArray& buf)
{if (buf.size() < 4)return 0;quint32 len = qFromBigEndian(*(qint32*)buf.data());//限制长度if (len > 1024 * 1024 * 1024)return -1;if (buf.size() >= len){qint32 commandId = qFromBigEndian(*(qint32*)(buf.data() + 4));qDebug() << "recv commandId: " << commandId;if (commandId == MsgType::heartbeat)qDebug() << "recv heartbeat";if (commandId == MsgType::other){//处理other消息 }return len;}return 0;
}
常见数据传输场景
一、概念
1)组包。
简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包。
2)半包。
指接受方没有接受到一个完整的包,只接受了部分,这种情况主要是由于TCP为提高传输效率,将一个包分配的足够大
,导致接受方并不能一次接受完
。
3)粘包与分包。
粘包:指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。
分包:指在出现粘包的时候我们的接收方要进行分包处理。
二、发送端解决办法
(1) 可以每次发送同样大小的包,过大的包不予发送,过小的包,后面部分用固定的字符’\0’进行填充。
(2)将流按字符处理,抽出一个字符做转义字符(通常Java用’\’来做转义字符,比如”\n”表示换行)。
(3)在发送方发送一个包的时候,先将这个包的长度发送给对方(一般是4个字节表示包长),然后再将包的内容发送过去.接收方先接收4个字节,看看包的长度,然后按照长度来接收包。
QT 处理TCP粘包问题相关推荐
- QT tcp粘包问题
QT tcp粘包问题 2016年12月27日 23:50:06 月下独奏 阅读数 1282更多 分类专栏: QT 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文 ...
- Qt中对TCP粘包的处理
当时用TCP协议传输数据时,经常出现粘包的现象 当服务器向客户端发送数据之后,客户端还没有接收数据的时候,这段时间数据在什么地方? 1.服务器?服务器已经发出数据了 2.网线?数据应该在内存,怎么会在 ...
- 【Netty】入门Netty官方例子解析(三)处理一个基于流的传输 TCP粘包和拆包问题分析和解决
关于 Socket Buffer的一个小警告 基于流的传输比如 TCP/IP, 接收到数据是存在 socket 接收的 buffer 中.不幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列. ...
- Socket编程(4)TCP粘包问题及解决方案
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...
- tcp协议缓冲区溢出_关于TCP 粘包拆包,你了解吗?
一.什么是粘包拆包? 粘包拆包是TCP协议传输中一种现象概念.TCP是传输层协议,他传输的是"流"式数据,TCP并不知道传输是哪种业务数据,或者说,并不关心.它只是根据缓冲区状况将 ...
- 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)
一.粘包/拆包概念 TCP是一个"流"协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的 ...
- Netty详解(五):Netty TCP粘包 拆包
1. 概述 无论是服务端还是客户端,我们读取或者发送消息的时候,都需要考虑TCP底层的粘包和拆包机制.下面我们来通过Netty来详解TCP底层的粘包和拆包机制. 2. TCP底层的粘包和拆包机制 TC ...
- 网络:TCP粘包问题?如何解决?
看面经时,看到有面试官问TCP的粘包问题.想起来研一做购物车处理数据更新时遇到粘包问题,就总结一下吧. 1 什么是粘包现象 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看, ...
- 6行代码解决golang TCP粘包
什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用golang的bufio.Scanner来实现自定义协议解包. 协议数据包定义 本文模拟一个日志服务器,该服务器接收客户端传到的数 ...
- 【Netty】TCP粘包和拆包
一.前言 前面已经基本上讲解完了Netty的主要内容,现在来学习Netty中的一些可能存在的问题,如TCP粘包和拆包. 二.粘包和拆包 对于TCP协议而言,当底层发送消息和接受消息时,都需要考虑TCP ...
最新文章
- thinkphp5.0 insert添加数据
- HTML4.0 / XHTML 1.0 Reference Manual
- java导出pdf字体宋体不加粗_docx4j word转pdf 中文宋体(中文正文)类型转换乱码...
- 计算文件的md5;vue计算文件md5值;计算图片的md5值;
- Django框架之Filters(过滤器)、母版的使用
- java 字符串转成图片_java 转换图片为字符串,将字符串转换成图片显示
- 2021年下半年网络工程师上午真题及答案解析
- 计算机网络实验1线缆制作,计算机网络技术实验报告1双绞线的制作
- Linux Matlab服务器进一步改造成Application Server(应用程序服务器)
- 条件概率与条件概率举例
- 手机web——自适应网页设计(html/css控制)
- cad卸载_CAD卸载不干净,如何清理CAD注册表
- 2020年C语言编程软件,c语言编程软件-精易csharp编程助手下载2020.07 正式安装版_久友下载站...
- 小爱同学app安卓版_小爱同学app下载_小爱同学官网版手机客户端下载 安卓版 V2.8.60 - 罐头安卓网...
- AABB与OOB包围盒子
- 踩坑指南!anaconda新建环境出错解决!又是猛男落泪的一天!
- Hills And Valleys(贪心/枚举)
- android 自定义星级评分控件
- Docker网络管理
- js逆向-ast混淆还原入门案例(2)
热门文章
- 遭遇希捷硬盘“固件门”,经销商仅赔了新硬盘,原来硬盘中数据全部丢失,郁闷。。。...
- 手机打印文件_Android 手机打印文件_Android 手机连接打印机_手机端打印wordExcelPPT_华为P20连接打印机_惠普M1213nf MFP打印机无线打印
- 基于Java开发的五子棋游戏APP设计与实现
- 看看世界各地牛人的彪悍乘车功夫
- php实现酒店客房管理系统,基于ssh/jsp/java/asp.net/php的酒店客房管理系统
- AotucCrawler 快速爬取美女图片
- linux大华客户端,rdesktop 下载-rdesktop(Linux下远程桌面客户端) 1.8.2 官方版 - 河东下载站...
- 软件企业 选择CodeMeter的十大理由
- Pycharm中Python包的下载与使用
- Futura字体和Logo设计实践