qt中记录数据的一次接收处理方法

引言

在udp通信中,发送请求后,等待接收端的响应,有时一个回应被分割成好几次发送,这种反馈的形式出现带有随机性,正常的情况下是一次反馈所有的数据,但是会出现一次反馈被分成好几次反馈。像下面这样:

请求:<history>
成功响应:<1,history,arg=78,total=1794,students=23><2,history,arg=65,total=1300,students=20><3,history,arg=73,total=1600,students=22>
<history,ok>
失败响应:<history,error>

发送请求后,接收端会返回给发送端所有的班级历史成绩的信息,本应该一次性返回,但是若随机出现接收端将要返回的数据分成好几次返回给发送端。像这样:

请求:<history>
响应:<1,history,arg=78,total=1794,students=23>

发送端接收到的数据并没有一次性返回,而是先接收一部分返回的数据,过一会儿后又接收到接收端返回的数据:

<2,history,arg=65,total=1300,students=20><3,history,arg=73,total=1600,students=22>

再过一会儿才接收到接收端返回的最后一句:

<history,ok>

上面描述的这种情况,本文记录的处理数据的方式,就是针对于上面所述的不能一次性返回一个响应给发送端。

方案

针对上面不能一次性返回一个响应的情况,下面来说一下如何接收这样的数据,使数据完整后再针对于上面的响应的格式来处理数据。

udp中常规接收数据的方式

 while (m_udp->hasPendingDatagrams()) {
        QByteArray byteArray;
        byteArray.resize(m_udp->pendingDatagramSize());
        QHostAddress ip;
        quint16 port;
        qint64 ret = m_udp->readDatagram(byteArray.data(),m_udp->pendingDatagramSize(),&ip,&port);
        qDebug()<<QStringLiteral("接收的数据:")<<byteArray.data()<<QStringLiteral("大小:")<<ret;
    }

上述不能一次性接收返回数据的情况不能用udp中常规接收数据的方式来接收,这样接收到的是一部分一部分的,需要再在数据处理里改动,为了使数据处理按照本文开始时给出的响应格式来解析,不改动数据处理部分,现在来调整接收数据的代码,使传送到数据处理时是一条完整的回复,当然必须满足响应数据一次性全部返回和响应数据一部分一部分的返回两种情况。

处理思路

如果是一次性返回响应的数据,直接传到数据解析函数中进行数据解析。
如果是一部分一部分的返回响应的数据,就将每一次返回的数据进行追加,构成一个字符串,直到接收到响应数据中含有<history,ok>或<history,error>将所有追加狗长城的字符串传入数据解析函数中。

处理实现

因为要数据进行追加成一个字符串,所以就需保存上一次的数据,将下一次接收的数据追击哀悼上一次数据的后面,直到最后接收到的数据中含<history,ok>或<history,error>。

QByteArray msgByteArray;//返回的数据是分开发送的(逐条发送),所以累计接收
    while (m_udp->hasPendingDatagrams()) {
        QByteArray byteArray;
        byteArray.resize(m_udp->pendingDatagramSize());
        QHostAddress ip;
        quint16 port;
        qint64 ret = m_udp->readDatagram(byteArray.data(),m_udp->pendingDatagramSize(),&ip,&port);
        msgByteArray.append(byteArray);
    }
    QString strTemp = msgByteArray;//临时保存接收的数据
    if (!strTemp.contains("ok")) {//是否接收数据中含有ok
        if (strTemp.contains("error")) {//请求失败
            qDebug()<<QStringLiteral("接收的字节数:")<<msgByteArray.size()<<QStringLiteral("数据:")<<msgByteArray.data();
            m_interface->onReceviedData(msgByteArray);//将接收的一次完整的响应回调给数据处理函数
        }else {//只回应了一部分数据,后面还有数据
            //保存此次接收的数据,等到结束标志<history,ok>到来的时候,与接收标志的数据叠加
            m_partByteArray = msgByteArray;//保存每一次接收的数据,并追加后面收到的数据
        }
    }else {
        if (!m_partByteArray.isEmpty()) {
            m_partByteArray.append(msgByteArray);
            msgByteArray.clear();
            msgByteArray = m_partByteArray;//为了使发送的数据依旧是msgByteArray,同时满足当返回响应是失败
            m_partByteArray.clear();
        }
        //直到接收到一次完整的数据
        qDebug()<<QStringLiteral("接收的字节数:")<<msgByteArray.size()<<QStringLiteral("数据:")<<msgByteArray.data();
        m_interface->onReceviedData(msgByteArray);
    }

上面这段代码的逻辑,既能满足一次性接收完整的响应(成功,失败的响应),也能满足一部分一部分的接收一次响应。 m_interface->onReceviedData(msgByteArray);是将接收到的一次完整的响应数据已回调的方式传递到数据处理函数中。

领悟

在qt下udp通信中数据接收的方式,还是要根据自己项目的需求来做适当的修改,并不是是常规接收数据那样一成不变的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肩上风骋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值