Results 1 to 12 of 12

Thread: Copy with QDataStream

  1. #1
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Question Copy with QDataStream

    I just try copy image with QDataStream. But failed

    Qt Code:
    1. QFile file("../olongia.png");
    2. file.open(QIODevice::ReadOnly);
    3.  
    4. QDataStream ods(&file);
    5. ods.setVersion(QDataStream::Qt_4_2);
    6.  
    7.  
    8.  
    9. QFile ftulis("../coba.png");
    10. ftulis.open(QIODevice::WriteOnly);
    11.  
    12. QDataStream wds(&ftulis);
    13. wds.setVersion(QDataStream::Qt_4_2);
    14.  
    15. wds << ods;
    16.  
    17. ftulis.close();
    18.  
    19. file.close();
    To copy to clipboard, switch view to plain text mode 

    Have any suggestion ?


    Sorry, my english is bad

  2. #2
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Copy with QDataStream

    datastream wont work because it puts some header information in the file.. which will corrupt the png file.
    just use simple fopen, fread, and fwrite or C library or use fstream of c++. If you just want to copy a file.. take a look at QFile::copy()

  3. #3
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Question Re: Copy with QDataStream

    I want learn how to send file with socket. So before that, i must learn how to copy file with use QDataStream. Or, you can give me simple code about send file with socket ? I have read some sample code how to send file via socket, but complex and so hard for me


    <i>Sorry, my english is bad </i>

  4. #4
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Copy with QDataStream

    why data stream is needed for socket?
    just read the file
    Qt Code:
    1. //open file, check error etc...
    2. QByteArray b=f.readAll();
    3. //open...
    4. t.write(b);
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Question Re: Copy with QDataStream

    I just try. But failed. This in my code. Can you help me for fix it ?

    Thank's before


    Btw, I created project with Qt-creator


    Server Code


    main.cpp

    Qt Code:
    1. #include <QtCore/QCoreApplication>
    2. #include "server.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QCoreApplication a(argc, argv);
    7.  
    8. Server server;
    9. if( !server.listen( QHostAddress::Any, 9876 ) )
    10. {
    11. qCritical( "Cannot listen to port 9876." );
    12. return 1;
    13. }
    14.  
    15. return a.exec();
    16. }
    To copy to clipboard, switch view to plain text mode 




    server.h

    Qt Code:
    1. #ifndef SERVER_H
    2. #define SERVER_H
    3.  
    4. #include <QtNetwork>
    5.  
    6. class Server : public QTcpServer
    7. {
    8.  
    9. public:
    10. Server();
    11.  
    12. protected:
    13. void incomingConnection( int descriptor );
    14.  
    15. };
    16.  
    17. #endif
    To copy to clipboard, switch view to plain text mode 





    server.cpp

    Qt Code:
    1. #include "server.h"
    2. #include "thread.h"
    3.  
    4. Server::Server() : QTcpServer()
    5. {
    6. }
    7.  
    8. void Server::incomingConnection( int descriptor )
    9. {
    10. ServerThread *thread = new ServerThread( descriptor, this );
    11.  
    12. connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
    13.  
    14. thread->start();
    15. }
    To copy to clipboard, switch view to plain text mode 





    thread.h

    Qt Code:
    1. #ifndef THREAD_H
    2. #define THREAD_H
    3.  
    4. #include <QtNetwork>
    5. #include <QtGui>
    6.  
    7. class ServerThread : public QThread
    8. {
    9. public:
    10. ServerThread( int descriptor, QObject *parent );
    11. void run();
    12.  
    13. private:
    14. int m_descriptor;
    15. };
    16.  
    17. #endif
    To copy to clipboard, switch view to plain text mode 





    thread.cpp

    Qt Code:
    1. #include "thread.h"
    2.  
    3. ServerThread::ServerThread( int descriptor, QObject *parent ) : QThread( parent )
    4. {
    5. m_descriptor = descriptor;
    6. }
    7.  
    8. void ServerThread::run()
    9. {
    10. QTcpSocket socket;
    11. if( !socket.setSocketDescriptor( m_descriptor ) )
    12. {
    13. qDebug( "Socket error!" );
    14. return;
    15. }
    16.  
    17.  
    18. QFile file("images/linux.png");
    19. QByteArray data=file.readAll();
    20. socket.write( data );
    21. socket.disconnectFromHost();
    22. //socket.waitForDisconnected();
    23. }
    To copy to clipboard, switch view to plain text mode 







    Client Code



    main.cpp

    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "dialog.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. Dialog w;
    8. w.show();
    9. return a.exec();
    10. }
    To copy to clipboard, switch view to plain text mode 



    dialog.h

    Qt Code:
    1. #ifndef DIALOG_H
    2. #define DIALOG_H
    3.  
    4. #include <QtGui>
    5. #include <QtNetwork>
    6.  
    7. namespace Ui
    8. {
    9. class Dialog;
    10. }
    11.  
    12. class Dialog : public QDialog
    13. {
    14. Q_OBJECT
    15.  
    16. public:
    17. Dialog(QWidget *parent = 0);
    18. ~Dialog();
    19.  
    20. private:
    21. Ui::Dialog *ui;
    22.  
    23. QTcpSocket socket;
    24.  
    25.  
    26. private slots:
    27. void on_pushButton_clicked();
    28.  
    29. void tcpReady();
    30. void tcpError( QAbstractSocket::SocketError error );
    31.  
    32. };
    33.  
    34. #endif // DIALOG_H
    To copy to clipboard, switch view to plain text mode 





    dialog.cpp

    Qt Code:
    1. #include "dialog.h"
    2. #include "ui_dialog.h"
    3.  
    4. Dialog::Dialog(QWidget *parent)
    5. : QDialog(parent), ui(new Ui::Dialog)
    6. {
    7. ui->setupUi(this);
    8.  
    9. connect( &socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(tcpError(QAbstractSocket::SocketError)) );
    10. connect( &socket, SIGNAL(readyRead()), this, SLOT(tcpReady()) );
    11.  
    12. }
    13.  
    14. Dialog::~Dialog()
    15. {
    16. delete ui;
    17. }
    18.  
    19. void Dialog::on_pushButton_clicked()
    20. {
    21.  
    22. socket.abort();
    23. socket.connectToHost( ui->lineEdit->text(), 9876 );
    24.  
    25. }
    26.  
    27.  
    28. void Dialog::tcpReady()
    29. {
    30.  
    31.  
    32. QByteArray ar=socket.readAll();
    33. QFile file("linuxmu.png");
    34. file.open(QIODevice::WriteOnly);
    35. QDataStream ds(&file);
    36. ds << ar;
    37.  
    38. file.close();
    39. }
    40.  
    41. void Dialog::tcpError( QAbstractSocket::SocketError error )
    42. {
    43. if( error == QAbstractSocket::RemoteHostClosedError )
    44. return;
    45. QMessageBox::warning( this, tr("Error"),
    46. tr("TCP error: %1").arg( socket.errorString() ) );
    47. ui->label->setText( tr("<i>No Image</i>") );
    48. ui->pushButton->setEnabled( true );
    49. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Copy with QDataStream

    what is the error?
    a quick look shows that at the server side you did not open the file before readAll().

  7. #7
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Copy with QDataStream

    1. open the file before reading it on server side
    2. dont use QDataStream on client side - use just file.write(data);
    3. When you send data through the network there is possibility that not all your data would be send in one network packet so the clients readAll() can give you less data than you sent from server! in your case it can result in corrupted image file. The best way is to make some header to your sent data like this:
    Qt Code:
    1. QByteArray data = file.readAll();
    2. int size = data.size();
    3. // now send size and then data
    To copy to clipboard, switch view to plain text mode 
    client:
    Qt Code:
    1. int size = readSize(socket.read(sizeof(int));
    2. // now check withc bytesAvailable()if you got all data
    3. // and read them, if not all you have to wait for next part and append
    4. // it to the already downloaded part
    5. data = socket.readAll();
    6. // or
    7. data.append(socket.readAll());
    To copy to clipboard, switch view to plain text mode 
    if your image is quite small then there is high possibility that it would be sent in one part,
    so the method I described would be necessary, but who knows :]
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  8. #8
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Question Re: Copy with QDataStream

    Server

    Qt Code:
    1. QFile file("images/linux.png");
    2. file.open(QIODevice::ReadOnly)
    3. QByteArray data=file.readAll();
    4. int size=data.size();
    5. socket.write( data );
    6. socket.disconnectFromHost();
    To copy to clipboard, switch view to plain text mode 
    How send size and data ?


    Client

    Qt Code:
    1. int size=readSize(socket.read(sizeof(int)));
    2. QByteArray ar=socket.readAll();
    3. QFile file("linuxmu.png");
    4. file.open(QIODevice::WriteOnly);
    5. file.write(ar)
    6. file.close();
    To copy to clipboard, switch view to plain text mode 

    How declared readSize ?

  9. #9
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Copy with QDataStream

    you can assume that you size can be stored in 32-bit (4 byte) long int - you can use qint32 (or even quint32 - size can't be less then 0).
    so you have to convert quint32 into QByteArray, writing there byte by byte of your quint32, something like this:
    Qt Code:
    1. quint32 size = ...; // your size
    2. QByteArray intBytes;
    3. for (int i = 0; i < 4; ++i) {
    4. quint8 b = (size >> (i*8)) & 0x000000ff;
    5. intBytes.append(b);
    6. }
    To copy to clipboard, switch view to plain text mode 
    on the client side you have to create a valid quint32 from a byte array:
    Qt Code:
    1. QByteArray intBytes = socket.read(4); // 4*8 = 32 bits
    2. quint32 size = 0; // init with 0 to be sure there is really 0
    3. for (int i = 0; i < 4; ++i) {
    4. quint8 b = intBytes.at(i);
    5. size |= (((quint32)b) & 0x000000ff) << i*8;
    6. }
    To copy to clipboard, switch view to plain text mode 
    (should work but i did not check so try to print the int first to see if it is what you have sent :])
    now you have the size, so whenever readyRead() comes from socket you have to check int the slot if you have to start reading new image (read size and some of data) or you are in the middle of image data. Whenever you read image data just check if bytesAvailable() are equal to the needed size, if less than readAll() and decrease size by a number of bytes you already read. and so on... In other words reading data becomes a little state machine :] so you have to react adequately to the state you are in.

    P.S. And it is nice to check if file was opened succesfully, so instead of this:
    Qt Code:
    1. file.open(QIODevice::ReadOnly);
    To copy to clipboard, switch view to plain text mode 
    better do it like this:
    Qt Code:
    1. if (!file.open(QIODevice::ReadOnly)) {
    2. // do something proper if cannot open file, e.g.:
    3. qDebug("Cannot open file!");
    4. return;
    5. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by faldzip; 9th July 2009 at 12:53. Reason: updated contents
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  10. #10
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Default Re: Copy with QDataStream

    Not work. But thank's

    I think not right to me for learn about QtNetwork now. Maybe next time

    Qt Code:
    1. QTcpSocket socket;
    2. if( !socket.setSocketDescriptor( m_descriptor ) )
    3. {
    4. qDebug( "Socket error!" );
    5. return;
    6. }
    7.  
    8.  
    9. QFile file("images/linux.png");
    10. if (!file.open(QIODevice::ReadOnly))
    11. {
    12. qDebug("Cannot open file!");
    13. return;
    14. }
    15.  
    16. QByteArray data=file.readAll();
    17. int size=data.size();
    18.  
    19. for(int i=0; i< 4; ++i)
    20. {
    21. quint8 b=(size >> (i*8)) & 0x000000ff;
    22. data.append(b);
    23. }
    24.  
    25. socket.write(data);
    26. socket.disconnectFromHost();
    To copy to clipboard, switch view to plain text mode 


    Client
    Qt Code:
    1. void Dialog::tcpReady()
    2. {
    3.  
    4. QByteArray ar=socket.read(4);
    5. quint32 size=0;
    6. for(int i=0; i < 4; ++i)
    7. {
    8. quint8 b=ar.at(i);
    9. size |= (((quint32)b) & 0x000000ff) << i*8;
    10. }
    11.  
    12. QFile file("linuxmu.png");
    13. file.open(QIODevice::WriteOnly);
    14. file.write(ar);
    15.  
    16. file.close();
    17. }
    To copy to clipboard, switch view to plain text mode 


    Once more, thank's for your help

  11. #11
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Copy with QDataStream

    Quote Originally Posted by wirasto View Post
    Not work. But thank's

    Qt Code:
    1. QTcpSocket socket;
    2. if( !socket.setSocketDescriptor( m_descriptor ) )
    3. {
    4. qDebug( "Socket error!" );
    5. return;
    6. }
    7.  
    8.  
    9. QFile file("images/linux.png");
    10. if (!file.open(QIODevice::ReadOnly))
    11. {
    12. qDebug("Cannot open file!");
    13. return;
    14. }
    15.  
    16. QByteArray data=file.readAll();
    17. int size=data.size();
    18.  
    19. for(int i=0; i< 4; ++i)
    20. {
    21. quint8 b=(size >> (i*8)) & 0x000000ff;
    22. data.append(b);
    23. }
    24.  
    25. socket.write(data);
    26. socket.disconnectFromHost();
    To copy to clipboard, switch view to plain text mode 
    Men you have appended your size to the end of the data! What is the sense of doing that if you have to know the size at the very beginning of receiving data??? You have to send the size, and then the data:
    Qt Code:
    1. QTcpSocket socket;
    2. if( !socket.setSocketDescriptor( m_descriptor ) )
    3. {
    4. qDebug( "Socket error!" );
    5. return;
    6. }
    7.  
    8.  
    9. QFile file("images/linux.png");
    10. if (!file.open(QIODevice::ReadOnly))
    11. {
    12. qDebug("Cannot open file!");
    13. return;
    14. }
    15.  
    16. QByteArray data=file.readAll();
    17. int size=data.size();
    18.  
    19. QByteArray sizeBytes;
    20. for(int i=0; i< 4; ++i)
    21. {
    22. quint8 b=(size >> (i*8)) & 0x000000ff;
    23. sizeBytes.append(b);
    24. }
    25.  
    26. sizeBytes.append(data);
    27. socket.write(sizeBytes);
    28. socket.disconnectFromHost();
    To copy to clipboard, switch view to plain text mode 
    it is not that hard to invent that idea.
    And you dont even use that information about size on the client side.
    Tell me what happend if you do it like this:
    Qt Code:
    1. void Dialog::tcpReady()
    2. {
    3. int bytesAvail = socket.bytesAvailable() - 4;
    4. QByteArray ar=socket.read(4);
    5. quint32 size=0;
    6. for(int i=0; i < 4; ++i)
    7. {
    8. quint8 b=ar.at(i);
    9. size |= (((quint32)b) & 0x000000ff) << i*8;
    10. }
    11.  
    12. if (size > bytesAvail)
    13. qDebug("Different sizes!!!");
    14. else
    15. qDebug("All data have been delivered!");
    16.  
    17. ar = socket.readAll();
    18. QFile file("linuxmu.png");
    19. file.open(QIODevice::WriteOnly);
    20. file.write(ar);
    21.  
    22. file.close();
    23. }
    To copy to clipboard, switch view to plain text mode 

    I think not right to me for learn about QtNetwork now.
    As I see you have to read about network at all...
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  12. The following user says thank you to faldzip for this useful post:

    wirasto (9th July 2009)

  13. #12
    Join Date
    May 2009
    Location
    Gorontalo
    Posts
    200
    Thanks
    20
    Thanked 5 Times in 5 Posts
    Qt products
    Platforms
    Unix/X11 Windows

    Smile Re: Copy with QDataStream

    Thank's because you keep teach me....
    And... your sample code work now

    Btw, I must put this line in server side

    Qt Code:
    1. socket.waitForDisconnected();
    To copy to clipboard, switch view to plain text mode 


    Sorry, my english is so bad

Similar Threads

  1. Replies: 1
    Last Post: 27th November 2014, 09:11
  2. Q_INTERFACES with classes having a copy constructor
    By Mike in forum Qt Programming
    Replies: 0
    Last Post: 31st October 2008, 12:40
  3. QObject and copy Constructors
    By December in forum Qt Programming
    Replies: 5
    Last Post: 17th July 2008, 16:14
  4. copy and run a .exe file in another system
    By sabeesh in forum Installation and Deployment
    Replies: 3
    Last Post: 22nd August 2007, 10:05
  5. QDataStream >> QString
    By smalls in forum Qt Programming
    Replies: 2
    Last Post: 17th January 2006, 22:14

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.