2015-10-09 2 views
2

Я не могу загрузить файл на FTP-сервер 000webhost.com, используя Indy для Lazarus. Я протестировал ftp-соединение с командной строкой Windows, и он отлично работает. Это мои настройки (IdFTP):Загрузить файл на FTP-сервер с помощью Indy

IdFTP1.Host:='shabala.com'; 
IdFTP1.Passive:=True; 
IdFTP1.TransferType:=ftBinary; 
IdFTP1.Username:='******'; 
IdFTP1.Password:='******'; 
IdFTP1.Port:=21; 

И это код, который я использую, чтобы позвонить мой TIdFTP компонент, IdFTP1:

IdFTP1.Connect(True); 
//IdFTP1.ChangeDir('/Sessions'); 
IdFTP1.Put(GetCurrentDir+'\'+Token+'.cmd',Token+'.cmd', False); 
IdFTP1.Quit; 
IdFTP1.Disconnect; 

где переменная Token объявлена ​​как:

Token: String; 

Когда я запускал программу в первый раз, она замерзала, и я объявил компонент TIdAntiFreeze, чтобы предотвратить его замораживание. Итак, вот что происходит сейчас: иногда программа работает нормально, но файлы не передаются на сервер (если я пытаюсь повторить загрузку, она дает мне ошибку EIdAlredyConnected), а иногда (если я немного изменил код , ничего лишнего), он дает мне EIdProtocolReplyError со странным сообщением. Я пытался поймать исключение и получить мою программу, чтобы отобразить сообщение, и у меня есть какие-то странные символы:

$ £ ï túÁÕÖ БВК) € ¶K ... ÅõÞl% ÇðåÀ¨Á «§pp
в% ~ßï7! ƒDªÉ [... o_ £ P * ¡° z1k ¢ H € ΨERPö/
üðÎƒç ± ïpļƒÏƒ <Ò1ì
мкА { »(г {å ¥ р ... Ž¹öÐR_JúѯuBûŸ € Œ Pp6o¯ с [JgžÎ¿Èà|Ä € VJþz'0è-`BO @ T

реакция выглядит следующим образом, если правильно отформатирован:

Strange response

Невозможно поместить здесь форматированный текст.

Сервер работает абсолютно нормально, каталоги, которые я пытаюсь загрузить, chmodded до 777, и я обнаружил, что размер файла (который я хочу загрузить) не превышает 3 КБ.

Любые идеи?

+0

By «подслушивания» Я предполагаю, что вы имеете в виду «замораживание» - так как вы пытались использовать 'TIdAntiFreeze', чтобы решить эту проблему? –

+0

Да. Кнопка, которой назначена процедура, осталась в «состоянии кликов». Это TBCButton (пакет BGRAControls). Кроме того, приложение не отвечало (если я нажал на форму, он разбился). @JerryDodge – TheGreenOmega

+0

Это потому, что 'TIdFTP' блокирует вызывающий поток, когда он занят работой (как и все компоненты Indy). Если вызывающий поток является основным потоком пользовательского интерфейса, вы не можете своевременно обрабатывать новые сообщения, если только вы не используете 'TIdAntiFreeze'. Лучше переместить 'TIdFTP' вместо рабочего потока. –

ответ

6

Я много лет боролся с Indy Ftp. В какой-то момент я обратился к альтернативному (бесплатному) клиенту Ftp от OverbyteIcs (click ICS and then click Download ICS-V8.16 (Apr, 2015)). Если вы не против использования бесплатного пакета, следующий код будет делать работу:

uses 
    ... 
    OverbyteIcsFtpCli; 

procedure FtpUploadFile( 
          HostName: String; 
          UserName: String; 
          Password: String; 
          UploadFileName: String; 
          ToHostDir : String); 
var 
    FTP: TFtpClient; 
begin 
    FTP := TFtpClient.Create(nil); 
    try 
    FTP.HostName := HostName; 
    FTP.Passive := True; 
    FTP.Binary := True; 
    FTP.Username := UserName; 
    FTP.Password := Password; 
    FTP.Port := '21'; 

    if not FTP.Open then 
     raise Exception.Create('Failed to connect: ' + FTP.ErrorMessage); 

    if (not FTP.User) or (not FTP.Pass) then 
     raise Exception.Create('Failed to login: ' + FTP.ErrorMessage); 

    FTP.HostDirName := ToHostDir; 
    if not FTP.Cwd then 
     raise Exception.Create('Failed to change dir: ' + FTP.ErrorMessage); 

    FTP.LocalFileName := UploadFileName; 
    FTP.HostFileName := ExtractFileName(UploadFileName); 

    if not FTP.Put then 
     raise Exception.Create('Failed to upload file: ' + FTP.ErrorMessage); 
    finally 
    FTP.Free; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    FtpLoadFile('rubilaxe.hostoi.com', 
        '******', '******', 
        IncludeTrailingPathDelimiter( 
          ExtractFilePath(Application.ExeName)) +'datafile.zip', 
        '/files' ); 
end;