Qt использует threadpools, не может получить все данные одновременно в readyRead()
Я новичок в QT и C++, я пытаюсь создать QTcpserver, используя QThreadpools, чтобы он мог обрабатывать несколько клиентов. Несколько клиентов могут подключаться без проблем. Но я пытаюсь отправить изображение с телефона 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 ответа
Решил проблему сохранения изображения путем сбора строки в переменной temp и, наконец, использовал 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, вы мне очень помогли спасибо. Спасибо всем за вашу помощь.
Вызов readAll()
не всегда будет читать полное изображение, поскольку оно, очевидно, не может знать размер изображения. Он будет читать только все доступные в настоящее время байты, которые могут быть меньше, чем весь ваш файл, или больше, если отправитель действительно быстр, и вы не можете возобновить чтение. Так же readyRead()
только информирует вас о наличии байтов, но не о том, что был получен целый файл. Это может быть один байт или сотни байтов.
Либо вы в первую очередь знаете размер вашего изображения, потому что оно всегда фиксированное, либо отправитель должен сообщить получателю количество байтов, которое он хочет отправить.
Тогда вы можете просто игнорировать все readyRead()
сигналы до bytesAvailable()
соответствует размеру вашего изображения и вызова readAll()
прочитать все изображение сразу. Или вы читаете всякий раз, когда есть доступные байты, и заполняете свой буфер до тех пор, пока число прочитанных байтов не совпадет с байтами, которые получатель сказал вам, что он отправит.