Results 1 to 7 of 7

Thread: QTcp[server and socket]: can't read file sent

  1. #1
    Join Date
    Sep 2012
    Posts
    9
    Qt products
    Platforms
    Windows

    Smile QTcp[server and socket]: can't read file sent

    Good morning,
    I’m looking for an example about sending a file from one pc to an other with QTcpSocket. I tried to create my own code. I have an application, in which, the user will choose a file from his DD ( all types) and send it to the TcpServer, this server will then send this file to the other clients.But, I have a problem, when i choose the file and i send it, in the client’s side, i have this message: file is sending , but in the server’s side, it shows me that the file isn’t recieved with it’s totaly bytes. Any suggestion please. This is the function for sending the file in the client’s side:
    Qt Code:
    1. void FenClient::on_boutonEnvoyer_2_clicked()
    2. {
    3. QString nomFichier = lineEdit->text();
    4. QFile file(lineEdit->text());
    5. if(!file.open(QIODevice::ReadOnly))
    6. {
    7. qDebug() << "Error, file can't be opened successfully !";
    8. return;
    9.  
    10. }
    11.  
    12. QByteArray bytes = file.readAll();
    13.  
    14. QByteArray block;
    15. QDataStream out(&block, QIODevice::WriteOnly);
    16.  
    17. out << quint32(0);
    18. out << nomFichier;
    19. out << bytes;
    20. out.device()->seek(0);
    21. out << quint32((block.size() - sizeof(quint32)));
    22.  
    23. qDebug() << "Etat : envoi en cours...";
    24. listeMessages->append("status : sending the file...");
    25.  
    26. socket->write(block);
    27. }
    To copy to clipboard, switch view to plain text mode 
    and the server side:
    Qt Code:
    1. void FenServeur::datarecieved()
    2. {
    3.  
    4. QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
    5.  
    6. if(socket == 0)
    7. {
    8. qDebug() << "no Socket!";
    9. return;
    10. }
    11.  
    12. forever
    13. {
    14. QDataStream in(socket);
    15. if(blockSize == 0)
    16. {
    17. if(socket->bytesAvailable() )
    18. {
    19. qDebug() << "Error < sizeof(quint32))";
    20. return;
    21. }
    22.  
    23. in >> blockSize;
    24. }
    25.  
    26. if(socket->bytesAvailable() < blockSize)
    27. {
    28. qDebug() << "data not recieved with its total bytes";
    29.  
    30. return;
    31. }
    32.  
    33. qDebug() << "!!!!!!";
    34. QByteArray dataOut;
    35. QString nameFile;
    36. in >> nameFile >> dataOut;
    37. QFile fileOut(nameFile);
    38. fileOut.open(QIODevice::WriteOnly);
    39. fileOut.write(dataOut);
    40. fileOut.close();
    41.  
    42. blockSize = 0;
    43. }
    44. }
    45.  
    46. void FenServeur::sendToAll(const QString &message)
    47. {
    48.  
    49. QByteArray paquet;
    50. QDataStream out(&paquet, QIODevice::WriteOnly);
    51.  
    52. out << (quint32) 0;
    53. out << message;
    54. out.device()->seek(0);
    55. out << (quint32) (paquet.size() - sizeof(quint32));
    56. for (int i = 0; i < clients.size(); i++)
    57. {
    58. clients[i]->write(paquet);
    59. }
    60.  
    61. }
    To copy to clipboard, switch view to plain text mode 
    So i can't write the file that the server recieved into a new file. Any suggestion please!! and thanks in advance

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcp[server and socket]: can't read file sent

    You are making a common mistake of assuming that if you send X bytes in one chunk, those X bytes will also arrive to the destination in one chunk, which is not true.

    The logic of your server side code is as follows:
    1. Create a data stream object on the socket
    2. If block size is not set, check if there is any data in the socket (1 byte is also "any"), if not then return.
    3. Read the block size (note: point of failure since the block size can be more than one byte long)
    4. if there is not enough data available, return to step 1.
    5. read the name and content from the stream and write it to the file.

    See the problem? By the way, the simplest possible algorithm of sending a file is:
    1. Write four bytes in network byte order representing the size of the file name
    2. Write the filename (e.g. UTF-8 encoded)
    3. Write eight bytes in network byte order representing the length of the file
    4. Until all the content is written to the socket, read a couple of bytes from the file and write them to the socket.

    And reading end called upon receiving the readyRead() signal:
    1. if there are less than 4 bytes available, return
    2. read four bytes and interpret them as the file name length (let's call it FLEN), store the length
    3. see if there are FLEN bytes available in the socket, if not return and next time start from (3)
    4. read the file name, open the file for writing
    5. see if there are eight bytes available in the socket -- if not, return and next time start from (5)
    6. read the size of the file and store it in CONTENTSIZE
    7. read up to CONTENTSIZE bytes from the socket, write them to the file and reduce CONTENTSIZE by the number of bytes read
    8. if CONTENTSIZE > 0, return and next time start from (7)
    9. close the file and report success

    This way you are not using QDataStream and your algorithm can simply be implemented in environment without Qt, if needed. Another benefit is that this way you can transmit a file larger than the available size of your RAM.

    Your implementation allows you to transmit only a file a bit shorter than half of available RAM (since you are keeping the file in memory twice -- once in "bytes" and once in "block").
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Sep 2012
    Posts
    9
    Qt products
    Platforms
    Windows

    Default Re: QTcp[server and socket]: can't read file sent

    thanks wysota for reply, I solved my problem using the code here: http://www.qtcentre.org/threads/4820...hrough+sockets

    Thanks again for your clear response

  4. #4
    Join Date
    Sep 2012
    Posts
    9
    Qt products
    Platforms
    Windows

    Default Re: QTcp[server and socket]: can't read file sent

    I have just a little problem.It is that the received file is modified in its content. Following the reception, when I open the file, I found a line added to the beginning of the file, indicating the path to access the file from the sender (who sent file), how can I fix it not to add this line to the file in the reception??
    Thanks

  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,593
    Thanks
    13
    Thanked 1,587 Times in 1,516 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTcp[server and socket]: can't read file sent

    I hope you didn't copy the other thread's generally unnecessary use of threads to do simple networking.

    If you followed wysota's logic above then sender is sending the file name followed by the file content and the receiver is receiving the file name followed by the file content. You control the receiver and the sender. If you don't want the receiver to write the file name into the the file then don't code it to write every received byte into the file (because some of them will be length values and the file name). Alternatively, if you don't want to the original file name transmitted with the file content then don't send it.

  6. #6
    Join Date
    Sep 2012
    Posts
    9
    Qt products
    Platforms
    Windows

    Default Re: QTcp[server and socket]: can't read file sent

    i tried to follow wysota's logic, but i didn't know how i do in order to begin reading from just the content!!!!

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcp[server and socket]: can't read file sent

    Most trivial approach would be to use an 'if' statement that checks some particular flag and skips (or not) some piece of code. A more advanced approach would be to implement a simple state machine driving the communication logic.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QTCP Socket Server and threads
    By cafu1007 in forum Qt Programming
    Replies: 21
    Last Post: 2nd November 2012, 16:00
  2. Can't read from socket
    By marekdor in forum Newbie
    Replies: 6
    Last Post: 9th August 2012, 11:06
  3. Replies: 2
    Last Post: 22nd May 2011, 21:31
  4. Wait in thread till QTcp socket have some thing to read
    By hasnain in forum Qt Programming
    Replies: 2
    Last Post: 14th September 2010, 12:46
  5. non GUI socket server
    By pdoria in forum Qt Programming
    Replies: 1
    Last Post: 3rd January 2008, 11:15

Tags for this Thread

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.