Проблема скорости загрузки по FTP: программирование сокетов .NET по сравнению с использованием объектов FtpWebRequest / Response - PullRequest
2 голосов
/ 25 января 2011

Я пытаюсь написать простое приложение на c #, которое загружает большое количество маленьких файлов с FTP-сервера.

Я пробовал два подхода:

1 - общее программирование сокетов

2 - использование объектов FtpWebRequest и FtpWebResponse

Скорость загрузки (для одного и того же файла) при использовании первого подхода варьируется от 1,5 с до 7 с, второй дает более менее одинаковые результаты - около 2,5 с каждый раз.

Учитывая, что примерно 1,4 с из этих 2,5 с занимают процесс инициализации объекта FtpWebRequest (только 1,1 с для получения данных), разница весьма значительна.

Вопрос в том, как добиться для 1-го подхода такой же стабильной скорости загрузки, что и для 2-го?

Для 1-го подхода проблема, похоже, заключается в следующем цикле (поскольку это занимает около 90% времени загрузки):

Int32 intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None);    
while (intResponseLength != 0)  
{  
  localFile.Write(buffer, 0, intResponseLength);  
  intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None);  
}

Эквивалентная часть кода для 2-го подхода (всегда занимает около 1,1 с для конкретного файла):

Int32 intResponseLength = ftpStream.Read(buffer, 0, intBufferSize);  
while (intResponseLength != 0)  
{  
  localFile.Write (buffer, 0, intResponseLength);  
  intResponseLength = ftpStream.Read(buffer, 0, intBufferSize);  
}  

Я пробовал буферы от 56 до 32 КБ - без существенной разницы.
Также создание потока в открытом сокете данных:

Stream str = new NetworkStream(dataSocket);  

и чтение его (вместо использования dataSocket.Receive)

str.Read(buffer, 0, intBufferSize);

не помогает ... на самом деле это даже медленнее.

Заранее спасибо за любые предложения!

1 Ответ

2 голосов
/ 25 января 2011

Вам необходимо использовать методы Socket.Poll или Socket.Select, чтобы проверить доступность данных. То, что вы делаете, не только замедляет работу, но и вызывает большую нагрузку на процессор. Опрос или Выбор дадут процессорное время до тех пор, пока данные не станут доступны или истечет время ожидания. Вы можете сохранить тот же цикл, но включить вызов одного из вышеперечисленных методов и поиграть с таймаутами (попробуйте значения от 10 мс до 500 мс, чтобы найти оптимальное для вашей задачи время ожидания).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...