Quote Originally Posted by raheelgup View Post
Transfer Rate problem :
The transfer rate is extremely slow and I get like 4-5 MBs/second from one local VM to my desktop.
If I just read like 400 MB, it takes 12-13 seconds. With transferring data over the socket, it takes a whopping 80 seconds.
You are definitely slowing things down by calling waitForBytesWritten. Since you are running this all on the main thread, you're causing the main thread to block, which prevents you from reading more data to send. I also see that you are reading data in pretty small chunks of 4096 bytes and writing to the socket the same 4096 byte chunks. You should increase the amount of data read from the file in one read operation and write the same amount of data to the socket. You can benchmark different values to determine the optimal read/write values, etc. Then change your Protocol::socketReadyRead() slot to ReadAll into a QByteArray and append the new data read to the existing QByteArray buffer. You should also make the QByteArray buf a class variable so that its contents can persist across calls to Protocol::socketReadyRead() because Protocol::socketReadyRead() will not always have all bytes sent available at once (in fact, it rarely does when reading/writing lots of data).

Parse the "records" that may be in the QByteArray by looking at the length of data you're prepending in Protocol::rite() and determining whether or not you have a complete data item. If you do, extract that data from the QByteArray, then remove that data from QByteArray using QByteArray::remove(0, len) so that it's no longer in the buffer and the next "record" is at position 0 in the QByteArray, etc.

One more comment, I don't see where you are writing the commands 'gd' and 'qu' to the socket in your code, but in Protocol::socketReadyRead() you don't seem to be expecting them to be proceeded with the length of the command data item. I would suggest that you be consistent and each packet of data written by your app should include some common prefix like a length of the data, the "command", followed by any data specific to the "command" type (could be nothing, etc). You may also consider using a command like 'dt' (or any other unique value you want) to denote this is file data, etc. This way you can consistently determine what the packet of data is to be used for, etc.

You may also consider some type of checksum or hash value of the data so that you can verify the contents on the receiving end. You'll have the length of the data and a checksum/hash that you could compute on the received data to ensure it matches the data that was sent. This is not uncommon in backing up files across a network. You're better off finding out that what you received doesn't match what was sent at the time the data is received, so you could implement a new command (like 'rt' for retry) to retransmit that block of data, etc.

Hope this gets you pointed in the right direction.

Regards,

Jeff