Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTCPSocket. Receiving corrupted QImage on server part

QTCPSocket. Receiving corrupted QImage on server part

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 2.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mandruk1331M Offline
    mandruk1331M Offline
    mandruk1331
    wrote on last edited by mandruk1331
    #1

    I have a client-server architecture the client send the a Video stream to the server part, if the frames size is not big than the frame is being sent ok, but if the frame is quite big (not sure about the sizes) than on the server side it's being corrupted, the lower part of the image is grey. I googled found that it's better to use QDataStream, but now the data can't be written into the socket. I get this error:
    QIODevice::write (QBuffer): ReadOnly device - the problem is that I don't use QBuffer so I don't understand why this error is rising;
    Code (Client):

    void _Camera::bytesWrittenC(qint64 b){
        qDebug()<<"Data is ready:"<<b;
    }
    void _Camera::ReadyReadC(){
        qDebug()<<"Ready read";
    
    }
    
    void _Camera::SendData(QImage &frame){
        QByteArray buffer;
        QDataStream out(buffer);
        out<<int(0);
        out<<frame;
        out.device()->seek(0);
        out<<buffer.size();
       // QBuffer buffer(&ba);
        //buffer.open(QIODevice::ReadWrite);
        //frame.save(&buffer, "JPEG");
        //ba.append("We did it");
        //socket.setOpenMode(QIODevice::ReadWrite);
        if(connectedToHostC == false){
        socket.connectToHost(QHostAddress::LocalHost,PORT,QIODevice::ReadWrite);
         connect(&socket,SIGNAL(readyRead()),this,SLOT(ReadyReadC()));
        connectedToHostC = true;
        }
        if(socket.isValid()){
            qDebug()<<"Socket is valid";
        }
        //socket.open(QIODevice::ReadWrite);
        if(socket.write(buffer)< buffer.size()){
            qWarning("Transmit error");
        }
        qDebug()<<"Bytes written"<<socket.waitForBytesWritten(2000);
        qDebug()<<"Bytes available"<<socket.bytesAvailable();
    
    
    }
    

    Server side code:

    TCPSocket::TCPSocket()
    {
        socket = new QTcpSocket;
        connect(&server,SIGNAL(newConnection()),this,SLOT(newConnectionS()));
    }
    void TCPSocket::ListenS(){
        if(server.listen(QHostAddress::LocalHost,PORT)){
            qDebug()<<"Server is listening";
        }
        else{
            qDebug()<<"Server cannot be started"<<server.errorString();
        }
    }
    void TCPSocket::newConnectionS(){
        qDebug()<<"Connected";
         //socket->open(QIODevice::ReadWrite);
         socket = server.nextPendingConnection();
          connect(socket,SIGNAL(readyRead()),this,SLOT(newImageReceived()));
    
        if(socket->isOpen()){
            qDebug()<<"Socket is open";
        }else {qDebug()<<"Socket cannot be opened"<<socket->errorString();}
    }
    
    void TCPSocket::newImageReceived()
    {
        qDebug()<<"Img rece";
        QByteArray ba;
        if(socket->bytesAvailable() <=0){
            qDebug()<<"Cannot read from socket"<<socket->errorString();
        }else{
            while(socket->bytesAvailable()>0){
            qDebug()<<"Server:"<<socket->bytesAvailable();
            ba += socket->readAll();
            }
        }
    
        QImage img = QImage::fromData(ba);
    
        socket->waitForReadyRead(2000);
        if(!img.isNull()){
        if(checkFrame(img)){
        //socket->write("1");
        qDebug()<<"Frame ok";
        }else{
            qDebug()<<"Frame not ok";
            //socket->write("0");
        }
        emit sendImage(img);
        }
    
    }
    

    Mandruk1331

    K 1 Reply Last reply
    0
    • mandruk1331M mandruk1331

      I have a client-server architecture the client send the a Video stream to the server part, if the frames size is not big than the frame is being sent ok, but if the frame is quite big (not sure about the sizes) than on the server side it's being corrupted, the lower part of the image is grey. I googled found that it's better to use QDataStream, but now the data can't be written into the socket. I get this error:
      QIODevice::write (QBuffer): ReadOnly device - the problem is that I don't use QBuffer so I don't understand why this error is rising;
      Code (Client):

      void _Camera::bytesWrittenC(qint64 b){
          qDebug()<<"Data is ready:"<<b;
      }
      void _Camera::ReadyReadC(){
          qDebug()<<"Ready read";
      
      }
      
      void _Camera::SendData(QImage &frame){
          QByteArray buffer;
          QDataStream out(buffer);
          out<<int(0);
          out<<frame;
          out.device()->seek(0);
          out<<buffer.size();
         // QBuffer buffer(&ba);
          //buffer.open(QIODevice::ReadWrite);
          //frame.save(&buffer, "JPEG");
          //ba.append("We did it");
          //socket.setOpenMode(QIODevice::ReadWrite);
          if(connectedToHostC == false){
          socket.connectToHost(QHostAddress::LocalHost,PORT,QIODevice::ReadWrite);
           connect(&socket,SIGNAL(readyRead()),this,SLOT(ReadyReadC()));
          connectedToHostC = true;
          }
          if(socket.isValid()){
              qDebug()<<"Socket is valid";
          }
          //socket.open(QIODevice::ReadWrite);
          if(socket.write(buffer)< buffer.size()){
              qWarning("Transmit error");
          }
          qDebug()<<"Bytes written"<<socket.waitForBytesWritten(2000);
          qDebug()<<"Bytes available"<<socket.bytesAvailable();
      
      
      }
      

      Server side code:

      TCPSocket::TCPSocket()
      {
          socket = new QTcpSocket;
          connect(&server,SIGNAL(newConnection()),this,SLOT(newConnectionS()));
      }
      void TCPSocket::ListenS(){
          if(server.listen(QHostAddress::LocalHost,PORT)){
              qDebug()<<"Server is listening";
          }
          else{
              qDebug()<<"Server cannot be started"<<server.errorString();
          }
      }
      void TCPSocket::newConnectionS(){
          qDebug()<<"Connected";
           //socket->open(QIODevice::ReadWrite);
           socket = server.nextPendingConnection();
            connect(socket,SIGNAL(readyRead()),this,SLOT(newImageReceived()));
      
          if(socket->isOpen()){
              qDebug()<<"Socket is open";
          }else {qDebug()<<"Socket cannot be opened"<<socket->errorString();}
      }
      
      void TCPSocket::newImageReceived()
      {
          qDebug()<<"Img rece";
          QByteArray ba;
          if(socket->bytesAvailable() <=0){
              qDebug()<<"Cannot read from socket"<<socket->errorString();
          }else{
              while(socket->bytesAvailable()>0){
              qDebug()<<"Server:"<<socket->bytesAvailable();
              ba += socket->readAll();
              }
          }
      
          QImage img = QImage::fromData(ba);
      
          socket->waitForReadyRead(2000);
          if(!img.isNull()){
          if(checkFrame(img)){
          //socket->write("1");
          qDebug()<<"Frame ok";
          }else{
              qDebug()<<"Frame not ok";
              //socket->write("0");
          }
          emit sendImage(img);
          }
      
      }
      
      K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      @mandruk1331

      If I understand your code correctly, you are writing the size of the image into the buffer and afterwards the image. Then you are sending the whole buffer via tcp.

      On the receiving side you are not reading the size values. Therefore they should be now in the image as well. This cannot work. You need to read the size int first. This gives you also the number of bytes to expect. At the moment it is not even ensured that you have received all bytes.

      Vote the answer(s) that helped you to solve your issue(s)

      mandruk1331M 1 Reply Last reply
      0
      • K koahnig

        @mandruk1331

        If I understand your code correctly, you are writing the size of the image into the buffer and afterwards the image. Then you are sending the whole buffer via tcp.

        On the receiving side you are not reading the size values. Therefore they should be now in the image as well. This cannot work. You need to read the size int first. This gives you also the number of bytes to expect. At the moment it is not even ensured that you have received all bytes.

        mandruk1331M Offline
        mandruk1331M Offline
        mandruk1331
        wrote on last edited by mandruk1331
        #3

        @koahnig At the moment I want to finish the client side and after the server part. On the client side the data is not being written into the socket because of this error:

        QIODevice::write (QBuffer): ReadOnly device
        

        And I don't understand why this error is being raised, what device it want to be open so I could write data.
        Or maybe you can help to fix the problem with the corrupted image?

        Mandruk1331

        K 1 Reply Last reply
        0
        • mandruk1331M mandruk1331

          @koahnig At the moment I want to finish the client side and after the server part. On the client side the data is not being written into the socket because of this error:

          QIODevice::write (QBuffer): ReadOnly device
          

          And I don't understand why this error is being raised, what device it want to be open so I could write data.
          Or maybe you can help to fix the problem with the corrupted image?

          K Offline
          K Offline
          koahnig
          wrote on last edited by
          #4

          @mandruk1331

          In here:

          void _Camera::SendData(QImage &frame)
          {
              QByteArray buffer;
              QDataStream out(buffer);
              out<<int(0);
              out<<frame;
              out.device()->seek(0);
              out<<buffer.size();
          

          you are using this constructor
          The documentation says:
          QDataStream::QDataStream(const QByteArray &a)
          Constructs a read-only data stream that operates on byte array a. Use QDataStream(QByteArray, int) if you want to write to a byte array.*
          Since QByteArray is not a QIODevice subclass, internally a QBuffer is created to wrap the byte array.

          and you are trying to write to it. The constructor above is mopre appropriate, because you can choose the openMode.

          Vote the answer(s) that helped you to solve your issue(s)

          mandruk1331M 1 Reply Last reply
          1
          • K koahnig

            @mandruk1331

            In here:

            void _Camera::SendData(QImage &frame)
            {
                QByteArray buffer;
                QDataStream out(buffer);
                out<<int(0);
                out<<frame;
                out.device()->seek(0);
                out<<buffer.size();
            

            you are using this constructor
            The documentation says:
            QDataStream::QDataStream(const QByteArray &a)
            Constructs a read-only data stream that operates on byte array a. Use QDataStream(QByteArray, int) if you want to write to a byte array.*
            Since QByteArray is not a QIODevice subclass, internally a QBuffer is created to wrap the byte array.

            and you are trying to write to it. The constructor above is mopre appropriate, because you can choose the openMode.

            mandruk1331M Offline
            mandruk1331M Offline
            mandruk1331
            wrote on last edited by
            #5

            @koahnig is it better to use QByteArray or QDataStream?

            Mandruk1331

            K 1 Reply Last reply
            0
            • mandruk1331M mandruk1331

              @koahnig is it better to use QByteArray or QDataStream?

              K Offline
              K Offline
              koahnig
              wrote on last edited by
              #6

              @mandruk1331

              The combination, as you use, seems to be perfect from my perspective (corrected for openMode of ocurse). QDataStream provides you the i/o-operators, which are not available with QByteArray.

              Note: I am not a fan of either class. I never used QDataStream and only rarely QByteArray. Typically, I am going for the STL versions there.

              Vote the answer(s) that helped you to solve your issue(s)

              mandruk1331M 1 Reply Last reply
              0
              • K koahnig

                @mandruk1331

                The combination, as you use, seems to be perfect from my perspective (corrected for openMode of ocurse). QDataStream provides you the i/o-operators, which are not available with QByteArray.

                Note: I am not a fan of either class. I never used QDataStream and only rarely QByteArray. Typically, I am going for the STL versions there.

                mandruk1331M Offline
                mandruk1331M Offline
                mandruk1331
                wrote on last edited by
                #7

                @koahnig In my project I use a combination of QBuffer and QByteArray but in the future I think to use QDataStream.

                Mandruk1331

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved