Почему мой вызов TransmitFile работает плохо по сравнению с другими методами? - PullRequest
1 голос
/ 05 января 2010

Сначала немного фона - Я пишу базовый 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 МБ / с, но постепенно уменьшается до 3 МБ / с. Используя FileZilla Server и IIS FTP, он поддерживает постоянную скорость передачи> 30 МБ / с. Поэтому я знаю, что он не работает на полную мощность. Я пробовал возиться с размером буфера, но это не улучшило производительность. Если у кого-нибудь есть предложения по более эффективному способу передачи файла, пожалуйста, дайте мне знать. Документация по API, кажется, предполагает, что TransmitFile был оптимизирован для моего приложения, поэтому я решил использовать его.
[Прошу прощения за отсутствие знаний о API Windows.]

Также все сокеты открываются на localhost.

Ответы [ 3 ]

3 голосов
/ 05 января 2010

Увеличили ли вы размер буфера TCP сокета (и, возможно, размер окна TCP), установив параметры сокета SO_SNDBUF и SO_RCVBUF перед началом передачи? (сделать это после привязки и перед подключением)?

Судя по звуку проблемы, более быстрый запуск, который затем замедляется, я предполагаю, что это проблема управления потоком TCP (вероятно, из-за того, что окно TCP меньше, чем вы хотели) Было бы полезно взглянуть на поток данных с помощью Wireshark (в идеале до и после изменений, которые я предлагаю выше).

См:

0 голосов
/ 30 января 2010

Я пытался добавить TransmitFile в мой код, но производительность была ужасной. Это будет просто сидеть там двадцать секунд, прежде чем начать загрузку.

Я читал, что он также кажется каким-то асинхронным, хотя это нигде не задокументировано. Кроме того, похоже, что это может привести к сбою приложения, если вы выполните определенные операции в неправильное время: social.msdn.microsoft.com

Плохая документация и плохая производительность == не используйте, в моей книге. Это две строки C # для загрузки файла в байт [] и записи его в вывод ...

0 голосов
/ 05 января 2010

Кажется, MSDN здесь не очень помогает, за исключением того, что он подтверждает, что TransmitFile должна быть правильной функцией для использования здесь. Вы уже пробовали это?

hFile

Дескриптор открытого файла, который передает функция TransmitFile. поскольку операционная система читает файл данные последовательно, вы можете улучшить производительность кэширования, открыв обрабатывать с помощью FILE_FLAG_SEQUENTIAL_SCAN.

РЕДАКТИРОВАТЬ: Следующим шагом, который я бы порекомендовал, было бы проверить, как это делает FileZilla (с открытым исходным кодом, не так ли?). Возможно, использование Windows API - не идеальный способ сделать это, хотя TransmitFile объявлен как производящая функция.

...