QT下TCP单发视频和同时发视频包和文本包的防粘包处理

第一步:定义TCP包的头head(单解包视频)

uint m_head;//定义通信需要的协议包头
QByteArray m_head_buffer;
m_head = 0xffff; m_head_buffer.append(m_head>>24).append(m_head>>16).append(m_head>>8).append(m_head);//将m_head分成“8个比特位”的4个char型的数据储存在m_head_buffer中

 

第二步:
QTcpSocket *m_tcp_socket;//接收到数据的套接字

 connect(m_tcp_socket, &QTcpSocket::readyRead, this, [=](){
        //将m_tcp_socket中的信息储存到recv_data
        QByteArray recv_data = m_tcp_socket->readAll();
        if(recv_data.isNull()) return; //recv_data没有收到套接字m_tcp_socket的信息,直接返回退出
        //recv_data收到了套接字m_tcp_socket的信息,将其储存到m_temp_buffer中
        m_temp_buffer.append(recv_data);
        //m_temp_buffer的size小于8,说明一个头都没收全.自定义TCP头为8,前四位为0xffff,后四位为数据包的大小
        if(m_temp_buffer.size() <=8) return;
        int index = m_temp_buffer.indexOf(m_head_buffer);//判断m_head_buffer在m_temp_buffer中的哪一个位置
        if(index == -1)
        {
            m_temp_buffer.clear(); return;
        }
        while(index != -1)
        {
            //优化m_temp_buffer储存的数据
            //将m_temp_buffer的第一个头(m_head_buffer)放到m_temp_buffer的首地址中
            m_temp_buffer = m_temp_buffer.mid(index);
            //判断头是否完整(不完整),截取完了之后还够不够8个字节
            //注意有两个判断-》if(m_temp_buffer.size() <= 8) 
            //第一个是判断收到的数据够不够8个字节
            //第二个是判断mid()函数截取后够不够8个字节
            if(m_temp_buffer.size() <= 8)
                return;
            //判断头完整(且有数据)
            else{
                uint buffer_size = 0;//准备储存TCP中head包含的后面数据大小的信息
                //m_temp_buffer.data()返回m_temp_buffer的首地址head的,前四位是0xffff,后四位是包的大小
                memcpy(&buffer_size, m_temp_buffer.data() + 4, 4);
                //数据包长度不足一帧
                if((uint)m_temp_buffer.size() < buffer_size + 8)
                    return;
                else{
                        QByteArray frame_buffer = m_temp_buffer.mid(8, buffer_size);
                        m_temp_buffer = m_temp_buffer.mid(buffer_size + 8);
                        this->PurseTcpVidioData(frame_buffer);//解析TCP数据
                }
            }
            index = m_temp_buffer.indexOf(m_head_buffer);
        }
    });

第一步:定义TCP包的头head(同时解视频包和文本包的防粘包处理)

uint m_head;//定义通信需要的协议包头
QByteArray m_head_buffer;
m_head = 0xffff; m_head_buffer.append(m_head>>24).append(m_head>>16).append(m_head>>8).append(m_head);//将m_head分成“8个比特位”的4个char型的数据储存在m_head_buffer中

 flag位标志位,flag=1,发送的包为视频包;flag=0,发送的包为文本包;等等类推

第二步:
QTcpSocket *m_tcp_socket;//接收到数据的套接字,开始解包操作

connect(m_tcp_socket, &QTcpSocket::readyRead, this, [=](){
        QByteArray recv_data = m_tcp_socket->readAll();
        if(recv_data.isNull()) return;
        m_temp_buffer.append(recv_data);
        if(m_temp_buffer.size() <= 12) return;
        //判断m_head_buffer在m_temp_buffer中的哪一个位置
        int index = m_temp_buffer.indexOf(m_head_buffer);
        if(index == -1)
        {
            m_temp_buffer.clear(); return;
        }
        while(index != -1)
        {
            //优化m_temp_buffer储存的数据
            //将m_temp_buffer的第一个头(m_head_buffer)放到m_temp_buffer的首地址中
            m_temp_buffer = m_temp_buffer.mid(index);
            //判断头是否完整(不完整)????
            if(m_temp_buffer.size() <= 12)
                return;
            else//判断头完整(且有数据)
            {
                uint buffer_size = 0;//准备储存TCP中head包含的后面数据大小的信息
                //m_temp_buffer.data()返回m_temp_buffer的首地址head的,前四位是0xffff,后四位是包的大小
                memcpy(&buffer_size, m_temp_buffer.data() + 4, 4);
                uint type_date = 0;
                memcpy(&type_date, m_temp_buffer.data() + 8, 4);
                //数据包长度不足一帧
                if((uint)m_temp_buffer.size() < buffer_size + 12)
                    return;
                else
                {
                    if(type_date==1){//这一步判断是解视频包
                        QByteArray frame_buffer = m_temp_buffer.mid(12, buffer_size);
                        m_temp_buffer = m_temp_buffer.mid(buffer_size + 12);
                        this->PurseTcpVidioData(frame_buffer);//解析TCP数据
                    }
                    else{//这一步判断是解文本包
                        QByteArray txt_buffer = m_temp_buffer.mid(12, buffer_size);
                        m_temp_buffer = m_temp_buffer.mid(buffer_size + 12);
                        qDebug()<<txt_buffer;//解析TCP数据
                         qDebug()<<"txt_buffer的大小"<<txt_buffer.size();
                        if(txt_buffer=="\x10")
                         AudioWaining();
                    }
                }
            }
            index = m_temp_buffer.indexOf(m_head_buffer);
        }
    });

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本课程详细、全面地介绍了 Qt中的各个技术细节,并且额外赠送在嵌入式端编写Qt程序的技巧。整个课程涵盖知识点非常多,知识模块囊括 Qt-Core 组件、QWidgets、多媒体、网络、绘图、数据库,超过200个 C++ 类的分析和使用,学完之后将拥有 Qt 图形界面开的非常坚实的功底。 每个知识点不仅仅会通过视频讲解清楚,并且会配以精心安排的实验和作业,用来保证学习过程中切实掌握核心技术和概念,通过实验来巩固,通过实验来检验,实验与作业的目的是现问题,现技术盲点,通过答疑和沟通夯实技术技能。注意:本套视频教程来源于线下的实体班级,因此视频中有少量场景对话和学生问答,对此比较介意的亲们谨慎购买。注意:本套视频教程含大量课堂源码,含对应每个知识点的精心编排的作业。由于CSDN官方规定在课程介绍中不能出现作者的联系方式,因此在这里无法直接给出QQ答疑号,视频中的源码、资料和作业文档链接统一在购买后从CSDN平台跟我沟通,我会及时回复跟进。注意:本套视频教程含全套10套作业题,覆盖所有视频知识点,循序渐进,各个击破,作业总纲如下:下面是部分作业题目展示,每道题都有知识点说明,是检验学习效果的一大利器:(部分作业展示,为了止盗图盗题对题干做了模糊处理)(部分作业展示,为了止盗图盗题对题干做了模糊处理)(部分作业展示,为了止盗图盗题对题干做了模糊处理)(部分作业展示,为了止盗图盗题对题干做了模糊处理)(部分作业展示,为了止盗图盗题对题干做了模糊处理)&hellip;&hellip; &hellip;&hellip;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值