开发者

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 speed开发者_开发问答s. 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.


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:

  • http://msdn.microsoft.com/en-us/library/ms819736.aspx - TCP window tuning
  • http://msdn.microsoft.com/en-us/library/ms740476(VS.85).aspx - setsockopt
  • http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control - TCP flow control
  • http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html - beware TCP flow control if using async networking APIs.


It seems MSDN isn't much of a help here, except that it confirms TransmitFile should be the right function to use here. Did you already try this?

hFile

A handle to the open file that the TransmitFile function transmits. Since the operating system reads the file data sequentially, you can improve caching performance by opening the handle with FILE_FLAG_SEQUENTIAL_SCAN.

EDIT: The next step I'd recommend would be to check how FileZilla does it (it's open source, isn't it?). Perhaps using Windows API is just not the perfect way to do this, although TransmitFile is stated as a performant function.


I tried adding TransmitFile to my code, but performance was terrible. It would just sit there for twenty seconds before starting the download.

I've read that it also seems to be asynchronous in some manner, although that's not clearly documented anywhere. Additionally, it sounds like it can cause your application to crash if you do certain operations at the wrong time: social.msdn.microsoft.com

Poor documentation and bad performance == don't use, in my book. It's two lines of C# to load a file into a byte[] and write it to the output...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜