Search code examples
c++winsocktransmitfile

Why is my call to TransmitFile performing poorly compared to other methods?


First, a bit of background -- I am writing a basic FTP server for a personal project. I'm currently working on retrieving files. My current implementation looks like this:

HANDLE hFile = CreateFile("file.tar.gz", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
TransmitFile(sd, hFile, fileSize, 65536, NULL, NULL, TF_USE_KERNEL_APC | TF_WRITE_BEHIND); 
CloseHandle(hFile);

It works, but the performance is questionable. At first, the transfer starts out at about 10 MB/s, but slowly decreases to about 3 MB/s. Using FileZilla Server and IIS FTP, it maintains consistent >30 MB/s transfer speeds. Therefore, I know it's not working to its full capacity. I've tried tinkering with the buffer size but it's not improved the performance. If anyone has any suggestions for a more efficient way to transfer the file, please let me know. The API documentation seems to suggest that TransmitFile was optimized for my application, which is why I chose to use it.
[Please excuse my lack of Windows API knowledge.]

Also, all of the sockets are opened on localhost.


Solution

  • Have you increased the socket's TCP buffer size (and potentially the TCP window size) by setting the the SO_SNDBUF and SO_RCVBUF socket options before you start transmitting? (do it after bind and before connecting)?

    From the sound of the problem, faster start which then slows down, I'd guess at it being a TCP flow control issue (probably due to the TCP window being smaller than you'd like). It would be useful to look at the data flow using Wireshark (ideally before and after the change that I suggest above).

    See: