我是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);
}
现在我不确定如何完全获取数据或以图像格式保存接收的数据。我想知道如何完全接收图像数据。请帮忙。
答案 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你是一个很好的帮助,谢谢。谢谢大家的帮助。