Your problem seems to be that you try to send all the data at once using write(), which simply enqueues the data in an unbounded buffer. Data will only be sent when you return to the event loop and calling flush() is a poor attempt at fixing a broken design. I suggest you take an asynchronous approach, just like you would use to read data.

You could add members to your class to keep track of how much data you have sent from your file. Simply making the QFile a member of the class may be enough. Then, connect the socket's encryptedBytesWritten() signal to a slot in your class, in which you first call encryptedBytesToWrite() to check how much data is yet to be sent and, if this number goes below a certain threshold, read some chunk of data from the file, write() it to the socket, and return to let control go back to the event loop and have the socket send whatever is waiting in its buffer. That way, you will keep memory usage under control by loading the file on demand as the data is sent over the network.

Note that this asynchronous design will spread through the program: instead of the current (synchronous) sendBlocks() method, you will need a method which starts sending data and returns immediately, and a signal that you emit when the work is done (emit this signal from within the slot connected to encryptedBytesWritten(), after reaching the end of, then closing, the file).

By the way, your program does connect encryptedBytesWritten() to some slot whose code your forgot to include in your snippet.