vc ++ - код клиента Ftp - загрузка файла очень медленная - PullRequest
1 голос
/ 31 марта 2011

Я пишу FTP-клиент для загрузки файла. Псевдокод выглядит примерно так:

{

    command_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    login...//

    pass.. // passive mode

    get the address from the reply ... // 

    data_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    connect the data_Socket to that address ..//

    open the file using createFile(....) //

    loop
    {
        char buf[1000];

        readFile and fill the buf //

        send(dataSocket,buf,..);
    }

}

Теперь проблема в том, что скорость загрузки составляет 20 кБ / с, хотя я загружаю файл на тот же компьютер. Но когда человек загрузил один файл, используя ftp, через локальную сеть (его машина была ubuntu), скорость загрузки составила 10 МБ / с. Я не могу понять логику этого.

Примечание. Я использую FTP-сервер FileZilla, который позволяет отображать скорость загрузки / получения файла клиента.

Ответы [ 3 ]

1 голос
/ 31 марта 2011

Размещение псевдокода скрывает, вероятно, важные проблемы с производительностью.Так что не ясно, как вы заполняете переменную buf. * ​​1001 *

Но вы не должны отправлять куски по 1000 байт.Это может заставить TCP отправлять ACK чаще, чем это необходимо, на стороне сервера.

1 голос
/ 31 марта 2011

Ваш псевдокод пропускает несколько важных деталей, но я возьму несколько предположений, чтобы компенсировать: -)

  • попробуйте сделать ваш сокет неблокирующим, используйте select (), чтобы узнать, когда вы можете писать в него, и записывать куски размером чуть менее 64 K
  • во время отправки вашего сокета (который теперь асинхронный) вы можете прочитать следующий фрагмент файла

Ваш псевдокод теперь становится:

{
   command_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    login...//
    pass.. // passive mode
    get the address from the reply ... // 
    data_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    /* set data socket to non-blocking  */
    connect the data_Socket to that address ..//
    open the file using createFile(....) //
    /* read a chunk */
    loop
    {
        select
        send data
        readFile and fill the buf //
    }
}

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

0 голосов
/ 31 марта 2011
  1. Я предлагаю использовать ввод-вывод с отображением в память
  2. Если вы хотите использовать ReadFile функцию API, не читайте на 1000 байт.

    2,1 Чтение 2 ^ k байтов (1024, 2048, 4096 и т. Д.)

    2.2 Читайте более 1024 байта за итерацию (для большого файла это слишком мало). Попробуйте увеличить его до 4 МБ или что-то в этом роде. Вы можете сделать это в зависимости от постоянного размера файла.

    2.3. Вы можете использовать асинхронный ввод-вывод для чтения следующего фрагмента из файла, когда предыдущий фрагмент отправляется через send.

Хм ... может быть, другие могут предложить больше.

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