Hello.
It was required to do file transfer through QTcpSocket. Googled many different options that confused me.
The first method was done through the transmission of the length of the block and then the block itself. But then I found a more advanced way through transactions, which appeared in Qt 5.7. I did it on it, asynchronously.
Please rate whether it is correctly and how much correctly done? If there are any comments, I will be glad to know them. Thank.

I pass in several variables:
- type of network packet (file, message or other)
If the file is:
- file name
- file size in bytes
- data block
- and at the end a text message

File Transfer Code:

Qt Code:
  1. enum PacketType
  2. {
  3. TYPE_NONE = 0,
  4. TYPE_MSG = 1,
  5. TYPE_FILE = 2,
  6. };
  7.  
  8. void TcpClient::socketSendMessage()
  9. {
  10. QDataStream stream(m_pTcpSocket);
  11. stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
  12.  
  13. stream << PacketType::TYPE_FILE;
  14.  
  15. QString fileName("/mnt/d/1.png");
  16. QFile file(fileName);
  17. QFileInfo fileInfo(file);
  18. qint64 fileSize = fileInfo.size();
  19.  
  20. stream << fileName;
  21. stream << fileSize;
  22.  
  23. int countSend = 0;
  24.  
  25. if (file.open(QFile::ReadOnly))
  26. {
  27. while(!file.atEnd())
  28. {
  29. QByteArray data = file.read(32768*8);
  30. stream << data;
  31. countSend++;
  32. }
  33. qDebug() << Tools::getTime() << "_CLIENT: ------------------------ countSend FINAL: " << countSend;
  34. }
  35.  
  36. file.close();
  37.  
  38. qDebug() << Tools::getTime() << "_CLIENT: send file ok";
  39.  
  40. QString testStr("TEST_MESSAGE");
  41. stream << testStr;
  42. }
To copy to clipboard, switch view to plain text mode 

File retrieval code:
Header file server:
Qt Code:
  1. #ifndef MYTCPSERVER_H
  2. #define MYTCPSERVER_H
  3.  
  4. #include <QObject>
  5. #include <QTcpServer>
  6. #include <QTcpSocket>
  7. #include "global.h"
  8. #include <QFile>
  9.  
  10.  
  11. class MyTcpServer : public QObject
  12. {
  13. Q_OBJECT
  14.  
  15. public:
  16. explicit MyTcpServer(QObject *parent = nullptr);
  17. ~MyTcpServer();
  18.  
  19. int number;
  20. QString str;
  21.  
  22. public slots:
  23. void slotNewConnection();
  24. void slotServerRead();
  25. void slotClientDisconnected();
  26. void onSocketReceiveMessage();
  27. void startServer();
  28.  
  29. private:
  30. QTcpServer * mTcpServer;
  31. QTcpSocket * mTcpSocket;
  32. qint64 sizeReceivedData;
  33. QString fileCopy;
  34. PacketType packetType;
  35.  
  36. QString filePath;
  37. qint64 fileSize;
  38. QString testStr;
  39. QByteArray tmpBlock;
  40. int countSend;
  41.  
  42. bool receiveFile(QDataStream &stream);
  43. };
  44.  
  45. #endif // MYTCPSERVER_H
To copy to clipboard, switch view to plain text mode 

In the server constructor:
Qt Code:
  1. packetType = PacketType::TYPE_NONE;
  2. filePath.clear();
  3. fileSize = 0;
  4. testStr.clear();
  5. sizeReceivedData = 0;
  6. tmpBlock.clear();
  7. countSend = 0;
To copy to clipboard, switch view to plain text mode 

Message receiving slot:
Qt Code:
  1. void MyTcpServer::onSocketReceiveMessage()
  2. {
  3. if (!mTcpSocket || !mTcpSocket->bytesAvailable())
  4. return;
  5.  
  6. qDebug() << Tools::getTime() << "SERVER: --------------------new-----------------------";
  7. qDebug() << Tools::getTime() << "SERVER: onSocketReceiveMessage: bytesAvailable" << mTcpSocket->bytesAvailable();
  8.  
  9. QDataStream stream(mTcpSocket);
  10. stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
  11.  
  12. // Getting PacketType
  13. if (packetType == PacketType::TYPE_NONE) {
  14. stream.startTransaction();
  15. stream >> packetType;
  16. if (!stream.commitTransaction()) {
  17. qDebug() << Tools::getTime() << "SERVER: packetType - FAIL commitTransaction";
  18. return;
  19. }
  20. qDebug() << Tools::getTime() << "SERVER: type:" << packetType;
  21. }
  22.  
  23. if (packetType == PacketType::TYPE_MSG)
  24. {
  25. //
  26. }
  27. else if (packetType == PacketType::TYPE_FILE)
  28. {
  29. //====================================================
  30. // Getting filePath
  31.  
  32. if (filePath.isEmpty()) {
  33. stream.startTransaction();
  34. stream >> filePath;
  35. if (!stream.commitTransaction()) {
  36. qDebug() << Tools::getTime() << "SERVER: filePath - FAIL commitTransaction";
  37. return;
  38. }
  39. qDebug() << Tools::getTime() << "SERVER filePath:" << filePath;
  40. }
  41.  
  42. //====================================================
  43. // Getting fileSize
  44.  
  45. if (!fileSize) {
  46. stream.startTransaction();
  47. stream >> fileSize;
  48. if (!stream.commitTransaction()) {
  49. qDebug() << Tools::getTime() << "SERVER: fileSize - FAIL commitTransaction";
  50. return;
  51. }
  52. qDebug() << Tools::getTime() << "SERVER: fileSize:" << fileSize;
  53. }
  54.  
  55. //====================================================
  56. // Getting file
  57.  
  58. if (sizeReceivedData != fileSize)
  59. {
  60. filePath = this->fileCopy; // temp replace file name
  61. QFile file(filePath);
  62. file.open(QFile::Append);
  63.  
  64. // Work with the file in the loop "while there is data in the socket"
  65. while (!mTcpSocket->atEnd())
  66. {
  67. //====================================================
  68. // Getting tmpBlock
  69.  
  70. stream.startTransaction();
  71. stream >> tmpBlock;
  72.  
  73. if (!stream.commitTransaction()) {
  74. qDebug() << Tools::getTime() << "SERVER: tmpBlock - FAIL commitTransaction";
  75. break;
  76. }
  77.  
  78. qint64 toFile = file.write(tmpBlock);
  79.  
  80. sizeReceivedData += toFile;
  81. countSend++;
  82.  
  83. tmpBlock.clear();
  84.  
  85. if (sizeReceivedData == fileSize)
  86. break;
  87.  
  88. } // while (!mTcpSocket->atEnd())
  89.  
  90. file.close();
  91.  
  92. } // if (sizeReceivedData != fileSize)
  93.  
  94. if (sizeReceivedData != fileSize)
  95. return;
  96.  
  97. qDebug() << Tools::getTime() << "SERVER: sizeReceivedData END: " << sizeReceivedData;
  98. qDebug() << Tools::getTime() << "SERVER fileSize ORIG:" << fileSize;
  99. qDebug() << "SERVER: countSend FINAL: " << countSend;
  100.  
  101.  
  102. //====================================================
  103. // Getting testStr
  104.  
  105. if (testStr.isEmpty()) {
  106. stream.startTransaction();
  107. stream >> testStr;
  108. if (!stream.commitTransaction()) {
  109. qDebug() << Tools::getTime() << "SERVER: testStr - FAIL commitTransaction";
  110. return;
  111. }
  112. qDebug() << Tools::getTime() << "SERVER: testStr:" << testStr;
  113. }
  114.  
  115. qDebug() << Tools::getTime() << "SERVER: END - bytesAvailable:" << mTcpSocket->bytesAvailable();
  116.  
  117. // Clear vars
  118. filePath.clear();
  119. fileSize = 0;
  120. tmpBlock.clear();
  121. sizeReceivedData = 0;
  122. testStr.clear();
  123. countSend = 0;
  124.  
  125. } // else if (packetType == PacketType::TYPE_FILE)
  126. }
To copy to clipboard, switch view to plain text mode