【问题标题】:Why is my call to TransmitFile performing poorly compared to other methods?为什么我对 TransmitFile 的调用与其他方法相比表现不佳?
【发布时间】:2011-01-01 10:57:18
【问题描述】:

首先,介绍一下背景—— 我正在为个人项目编写一个基本的 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 服务器和 IIS FTP,它保持一致的 >30 MB/s 传输速度。因此,我知道它没有充分发挥作用。我尝试过修改缓冲区大小,但并没有提高性能。 如果有人对更有效的文件传输方式有任何建议,请告诉我。 API 文档似乎表明 TransmitFile 已针对我的应用程序进行了优化,这就是我选择使用它的原因。
[请原谅我缺乏 Windows API 知识。]

此外,所有套接字都在 localhost 上打开。

【问题讨论】:

标签: c++ winsock transmitfile


【解决方案1】:

似乎MSDN 在这里没有太大帮助,只是它确认 TransmitFile 应该是在这里使用的正确函数。你已经试过了吗?

h文件

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

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

【讨论】:

  • 添加该标志可能在中间有所帮助 - 它似乎最终以大约 6 Mb/s 的速度触底。
【解决方案2】:

您是否在开始传输之前通过设置SO_SNDBUF 和SO_RCVBUF 套接字选项来增加套接字的TCP 缓冲区大小(可能还有TCP 窗口大小)? (绑定后连接前做)?

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

见:

【讨论】:

  • 这帮助很大。我从未真正见过这些选项。谢谢!
【解决方案3】:

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-09-18
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
相关资源
最近更新 更多