与其他方法相比,为什么我对 TransmitFile 的调用性能较差?

发布于 2024-08-16 18:47:07 字数 625 浏览 6 评论 0原文

首先,介绍一些背景知识—— 我正在为个人项目编写一个基本的 FTP 服务器。我目前正在努力检索文件。我当前的实现如下所示:

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);

它有效,但性能值得怀疑。起初,传输速度约为 10 MB/s,但慢慢降至约 3 MB/s。使用 FileZilla Server 和 IIS FTP,它可以保持一致的 >30 MB/s 的传输速度。因此,我知道它没有充分发挥作用。我尝试过调整缓冲区大小,但并没有提高性能。 如果有人对更有效的文件传输方式有任何建议,请告诉我。 API 文档似乎表明 TransmitFile 已针对我的应用程序进行了优化,这就是我选择使用它的原因。
[请原谅我缺乏 Windows API 知识。]

此外,所有套接字都在本地主机上打开。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒几许 2024-08-23 18:47:07

在开始传输之前,您是否通过设置 SO_SNDBUFSO_RCVBUF 套接字选项来增加套接字的 TCP 缓冲区大小(以及可能的 TCP 窗口大小)? (在绑定之后和连接之前执行)?

从问题的声音来看,启动速度较快,然后速度减慢,我猜测这是 TCP 流量控制问题(可能是由于 TCP 窗口比您想要的小)。使用 Wireshark 查看数据流会很有用(最好是在我上面建议的更改之前和之后)。

请参阅:

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:

孤独患者 2024-08-23 18:47:07

看来 MSDN 并没有太多此处提供帮助,只是它确认 TransmitFile 应该是此处使用的正确函数。你已经尝试过这个了吗?

h文件

TransmitFile 函数传输的打开文件的句柄。自从
操作系统读取文件
数据顺序,你可以改进
通过打开缓存性能
使用 FILE_FLAG_SEQUENTIAL_SCAN 进行处理。

编辑:我建议的下一步是检查 FileZilla 是如何做到这一点的(它是开源的,不是吗?)。尽管 TransmitFile 被声明为高性能函数,但也许使用 Windows API 并不是执行此操作的完美方法。

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.

壹場煙雨 2024-08-23 18:47:07

我尝试将 TransmitFile 添加到我的代码中,但性能很糟糕。在开始下载之前,它只会在那里停留二十秒。

我读到它似乎也以某种方式异步,尽管没有在任何地方明确记录。此外,如果您在错误的时间执行某些操作,听起来可能会导致您的应用程序崩溃:
social.msdn.microsoft。 com

糟糕的文档和糟糕的性能==不要使用,在我的书中。将文件加载到 byte[] 并将其写入输出需要两行 C#...

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文