2012-11-30 22 views
0

我是QT和C + +新手,我想创建一个QTcpserver使用QThreadpools,因此它可以处理多个客户端。多个客户端能够无任何问题地连接。但是我试图从Android手机发送一个图像,脚本“IMGPNG”,指示图像数据的结束。现在,readyRead信号发出时的问题我正在读取所有可用数据,然后稍后执行一些字符串操作并重建图像。我不知道如何接收每个客户的完整图像,然后相应地处理它。Qt使用线程池,无法一次接收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); 


} 

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

+1

我会建议使用boost Asio代替网络,因为Qt实现中有可能导致数据丢失的错误。如果你想坚持使用Qt来处理这些事情,可以看看财富服务器/客户端的例子。 – Pete

+2

不要检查'bytesAvailable'。请阅读尽可能多的内容。如果你没有得到全部,请阅读更多内容。 –

回答

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方法图像 - > SaveImage,@DavidSchwartz你是一个伟大的帮助谢谢。感谢你的帮助。

3

readAll()的调用并不总是读取完整的图像,因为它显然无法知道图像的大小。它只会读取当前可用的所有字节,可能少于整个文件,或者如果发件人速度非常快,而且无法阅读,则会更多。 readyRead()只能通知您有可用的字节,但不能收到整个文件。它可能是一个字节或几百个字节。

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

然后你可以不理会所有readyRead()信号,直到bytesAvailable()匹配您的图片大小,并呼吁readAll()一次读取整个图像。或者,只要有可用字节并读取缓冲区,直到读取的字节数与接收方告诉您他将发送的字节数相匹配为止。

+1

谢谢您的回复。由于我不知道传入图像的大小,因此我需要修复一个缓冲区大小,然后读取所有可用的字节。我现在会尝试实现这一点。再次感谢。 – Jerry

+0

嗨,这是我所做的,但我似乎无法得到数据变量中的完整图像,我做错了什么。/**代码**/qint64 blockSize = 90000; if(socket-> bytesAvailable() read(data,blockSize); qDebug()<<“Data 1st in:”<< data; – Jerry

+0

你为什么使用'malloc()'?这是C++:/。你写道,你不知道图像的大小,但你仍然尝试读取* 90000 *字节。这是行不通的。你也必须检查'bytesRead'是否与你的图像大小相匹配。 – scai