2012-11-30 3 views
0

QT 및 C++의 초보자입니다. QThreadpools를 사용하여 QTcpserver를 만들려고 노력 중이므로 여러 클라이언트를 처리 할 수 ​​있습니다. 여러 클라이언트가 문제없이 연결할 수 있습니다. 하지만 이미지 데이터의 끝을 나타내는 "IMGPNG"꼬리말을 사용하여 Android 휴대 전화에서 이미지를 보내려고합니다. 이제 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

데이터 손실로 이어질 수있는 버그가 Qt 구현에 있기 때문에 네트워킹 대신 boost Asio를 사용하는 것이 좋습니다. 그 측면에서 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); 

       } 
      } 

     } 

- > SaveImage, @DavidSchwartz 당신은 큰 도움 감사했습니다. 도와 주셔서 감사합니다.

3

readAll()에 대한 호출은 분명히 이미지의 크기를 알 수 없기 때문에 항상 전체 이미지를 읽을 수있는 것은 아닙니다. 전체 파일보다 적은 현재 사용 가능한 모든 바이트 만 읽거나 보낸 사람이 정말 빠르며 읽는다면 따라 잡을 수 있습니다. 같은 방법으로 readyRead()은 사용할 수있는 바이트가 있지만 전체 파일이 수신되지 않았 음을 알립니다. 1 바이트 또는 수백 바이트 일 수 있습니다.

이미지의 크기가 항상 고정되어 있거나 발신자가 전송하려는 바이트 수를 수신자에게 알려야하기 때문에 이미지의 크기를 알 수 있습니다.

bytesAvailable()이 이미지 크기와 일치 할 때까지 readyRead() 신호를 모두 무시하거나 readAll()으로 전화를 걸어 한 번에 전체 이미지를 읽을 수도 있습니다. 또는 사용 가능한 바이트가있을 때마다 읽고 읽고 읽은 바이트 수가 수신자가 전송할 것이라고 말한 바이트와 일치 할 때까지 버퍼를 채 웁니다.

+1

답장을 보내 주셔서 감사합니다. 들어오는 이미지의 크기를 알지 못하기 때문에 버퍼 크기를 수정 한 다음 사용 가능한 모든 바이트를 읽습니다. 나는 이것을 시도하고 구현할 것이다. 다시 한번 감사드립니다. – Jerry

+0

안녕하세요, 내가 한 일이지만 데이터 변수에서 전체 이미지를 가져올 수없는 것 같습니다. 무엇이 잘못 되었나요?/** 코드 **/qint64 blockSize = 90000; if (socket-> bytesAvailable() 읽기 (데이터, 블록 크기); qDebug() << "Data 1st in :"<< 데이터; – Jerry

+0

왜 당신은'malloc()'을 사용하고 있습니까? 이것은 C++입니다 : /. 당신은 이미지의 크기를 알지 못하지만 여전히 * 90000 * 바이트를 읽으려고합니다. 이것은 작동하지 않습니다. 또한'bytesRead'가 이미지 크기와 일치하는지 확인해야합니다. – scai