Qt使用线程池,无法在readyRead()中一次接收所有数据

时间:2012-11-30 13:04:11

标签: qt sockets qtcpserver

我是QT和C ++的新手,我正在尝试使用QThreadpools创建一个QTcpserver,以便它可以处理多个客户端。多个客户端可以毫无问题地连接。但我正试图从Android手机发送图像,页脚为“IMGPNG”,表示图像数据结束。现在发出readyRead信号的问题我想读取所有可用数据,然后再执行一些字符串操作并重建图像。我不确定如何接收每个客户的完整图像,然后相应地处理它。

 void VireClients::readyRead()//read ready
{

 int nsize = socket->bytesAvailable();//trying to check the available bytes

 qDebug()<< "Bytes Available" << nsize;

 while(socket->bytesAvailable() < nsize){

     QByteArray data = socket->readAll();//how to receive all the data and then process it

 }

   /*!These lines call the threadpool instance and reimplement run*/
   imageAnalysis = new VireImageAnalysis(); //creating a new instance of the QRunnable
   imageAnalysis->setAutoDelete(true);
      connect(imageAnalysis,SIGNAL(ImageAnalysisResult(int)),this,SLOT(TaskResult(int)),Qt::QueuedConnection);
   QThreadPool::globalInstance()->start(imageAnalysis);


}

现在我不确定如何完全获取数据或以图像格式保存接收的数据。我想知道如何完全接收图像数据。请帮忙。

2 个答案:

答案 0 :(得分:3)

readAll()的调用并不总是会读取完整的图像,因为它显然无法知道图像的大小。它只会读取所有当前可用的字节,这些字节可能小于整个文件,如果发送者速度非常快而您无法读取,则会更多。同样的方式readyRead()只会通知您有可用的字节,但没有收到整个文件。它可以是单个字节或数百个字节。

您首先要知道图像的大小,因为它总是固定的,或者发送者必须告诉接收者他想要发送的字节数。

然后,您可以忽略所有readyRead()信号,直到bytesAvailable()与您的图片大小匹配,然后拨打readAll()一次读取整个图片。或者,只要有可用的字节,就会读取并填充缓冲区,直到读取的字节数与接收方告诉您将发送的字节数相符。

答案 1 :(得分:0)

通过收集临时变量中的字符串来解决保存图像问题,最后使用opencv imwrite来保存图像,这解决了这个问题:

 while(iBytesAvailable > 0 )
     {
      if(socket->isValid())
      {
       char* pzBuff = new char[iBytesAvailable];
       int iReadBytes = socket->read(pzBuff, iBytesAvailable);
       if( iReadBytes > 0 )
       {
           result1 += iReadBytes;

            str += std::string(reinterpret_cast<char const *>(pzBuff), iReadBytes);


            if(str.size() > 0){
                search = str.find("IMGPNG");

                if(search == result1-6){

                    finalID = QString::fromStdString(str);

                    Singleton_Global *strPtr = Singleton_Global::instance();
                    strPtr->setResult(finalID);

                    /*!Process the received image here*/
                    SaveImage= new VSaveImage();
                    SaveImage->setAutoDelete(false);
                    connect(SaveImage,SIGNAL(SaveImageResult(QString)),this,SLOT(TaskResult(QString)),Qt::QueuedConnection);
                    threadPool->start(SaveImage);

                }
            }

       }

最后在run方法上保存了图像 - &gt; SaveImage,@ DavidSchwartz你是一个很好的帮助,谢谢。谢谢大家的帮助。