QT tcp粘包问题

当两次发送时间过短,两次发送的数据包将会合成一个,对数据解读也就会出现错误。

解决方法:对数据进行包装,分为两部分,前面一部分存储数据总共的大小,后面一部分存储数据;

下面为例子

void transmission::readMessage()                                                 //连接信号槽,当有数据时触发
{
    QByteArray  xinxi;
    qDebug()<<"有数据传输!!";
 
 
    qDebug()<<"bytesAvailable"<<tcpSocket->bytesAvailable()<<"    ";
 
 
    while(tcpSocket->bytesAvailable()>0)
    {
  
 
 
 
 
 
 
        QDataStream dts(tcpSocket);
        /*********bytesreceived为0就为第一次接收 ************/
        if(bytesreceived==0)
        {
            qDebug()<<"第一次接受";
            //|如果是第一次接收
            if(tcpSocket->bytesAvailable()>=sizeof(qint64))
            {
                //|如果发送完了 总大小数据块
               // qDebug()<<sizeof(qint64);
 
 
                dts>>bytestotal;
               qDebug()<<"总共大小"<<bytestotal;                    
                                                                //bytestotal是这个包的数据大小
 
 
 
 
                bytesreceived+=sizeof(qint64);
 
 
                if(bytesreceived+tcpSocket->bytesAvailable()==bytestotal)
                {
                    //|如果第一次响应(一次性就发送了所有数据)就接收
                    qDebug()<<"一次性接受完成";
 
 
                    dts>>xinxi;
                    QString json_str(xinxi);
                    message=json_str;
 
 
 
 
 
 
                    /*********** 此次数据发送动作完毕*********清除一些成员属性*****方便于不断开连接情况下 第二次发送数据******/
                    bytesreceived=0;
                    bytestotal=0;
                    reciverfinish=true;
                }
                else if(bytesreceived+tcpSocket->bytesAvailable()>bytestotal)    //已经接受的数据加上未接受的数据大于包的数据,明显是粘包了
                {                                                                 进行处理
                    dts>>xinxi;
 
 
                    qDebug()<<"发生粘包"<<xinxi.size();
                    qDebug()<<tcpSocket->bytesAvailable();
                    bytesreceived=0;
                    reciverfinish=true;
                    bytestotal=0;
                   // dts.readBytes()
                }
            }
            else
            {
 
 
            }
 
 
        }
        else
        {
            /*******bytesreceived不为0 则不为第一次 响应(这个文件很大,或者 网络状态不是很好)*********/
            /*****************
                    * 每次就会响应这里 直到 数据接收够了 为止
                    ******************/
 
 
            if(bytesreceived+tcpSocket->bytesAvailable()>=bytestotal)
            {
                qDebug()<<"多次接受完成数据";
 
 
 
 
                dts>>xinxi;
                QString json_str(xinxi);
                message=json_str;
                qDebug()<<message;
                // this->ui->textBrowser->append(QString::number(this->bytestotal)+"----"+data+"<br/>");
 
 
 
 
 
 
                /*********** 此次数据发送动作完毕*********清除一些成员属性**方便于不断开连接情况下 第二次发送数据*********/
                bytesreceived=0;
                reciverfinish=true;
                bytestotal=0;
            }
 
 
 
 
        }
 
 
        QJsonParseError json_error;
        QJsonDocument parse_doucment = QJsonDocument::fromJson(xinxi, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        {
 
 
            if(parse_doucment.isObject())
            {
 
 
                Processingjsondata(xinxi);
            }
            else if(parse_doucment.isArray())
            {
     //           qDebug()<<"是JSONARRAY数据";
                Processingjsonarraydate(xinxi);
            }
            else
            {
     //           qDebug()<<"无法识别数据";
            }
        }
        else
            qDebug()<<json_error.error;
 
 
        QTime t;
            t.start();
            while(t.elapsed()<10)
                QCoreApplication::processEvents();
 
 
    }
 
 
 
 
}

猜你喜欢

转载自blog.csdn.net/d7185540/article/details/53900603