Solved

FTP Component

Posted on 2002-06-25
38
684 Views
Last Modified: 2011-09-20
Hi,
I need an FTP component that can work Async. I've tried ICS FTP component but its putAsync method is also not working properly. Only one thread works at a time.
plz help.
0
Comment
Question by:m_adil
  • 23
  • 9
  • 2
  • +4
38 Comments
 
LVL 1

Expert Comment

by:pr_wainwright
ID: 7109749
have you tried winshoes/indy ?.
0
 
LVL 22

Expert Comment

by:mnasman
ID: 7109759
Hello

did u try indy components?
http://www.nevrona.com/indy/
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109777
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109795
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109805
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109827
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109864
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109899
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7109940
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7110008
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7110100
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7110146
wtf ? .. did you hit refresh 8 times ?
anyway Indy is blocking
so if you want the download to run in the background create a thread and place that download there
another solution is to use the TidAntiFreeze component
it will give your apps responsivness back and allow other functions to work
but you really should go with multithreading

another option is to use f.pietes ICS components
they can work in Async or Sync
http://users.swing.be/francois.piette/icsdocuk.htm
0
 
LVL 1

Author Comment

by:m_adil
ID: 7110289
yes I did. but they didn't work for me either. Is there any special command/property for indy to get the file Async. ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7110325
Lee...
>>another option is to use f.pietes ICS components
they can work in Async or Sync

I've tried f.pietes FTP component. but it is also not working.

here is the sample code. button 1 connects the components to the FTP server and button 2 starts Async transfer. but file #2 actually starts transferring after #1 finishes.

I placed 2 FTP components on the form

procedure TForm1.Button2Click(Sender: TObject);
begin

   with FtpClient1 do
   begin
      HostName:= 'adil';
      UserName := 'anonymous';
      PassWord := 'as@as.as';
      LocalFileName := 'c:\temp\file1.exe';
      HostFileName := '/file1.exe';
      ConnectAsync;
   end;

   with FtpClient2 do
   begin
      HostName:= 'adil';
      UserName := 'anonymous';
      PassWord := 'as@as.as';
      LocalFileName := 'c:\temp\file2.exe';
      HostFileName := '/file2.exe';
      ConnectAsync;
   end;

end;


procedure TForm1.FtpClient2Progress(Sender: TObject; Count: Integer;
  var Abort: Boolean);
begin
   Gauge2.Progress :=  count*100 div 3787246;
end;

procedure TForm1.FtpClient1Progress(Sender: TObject; Count: Integer;
  var Abort: Boolean);
begin
   Gauge1.Progress :=  count*100 div 4327305;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
FtpClient1.PutAsync;
FtpClient2.PutAsync;
end;
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7110498
hum
weird .. I never worked with ICS .. only Indy
you could also try TMonsterFTP
it has nice gui treeview and listview included
very simple to use
supports drag'n'drop
but in my case it didn't work well in LAN
it ended file transfers prematurelly
but it did work async as I've tested it

I'll say it again... go for Indy with Multithreading
if you do I can help you out otherwise I'm out of ideas
0
 
LVL 1

Author Comment

by:m_adil
ID: 7111928
ok. how can I use indy with multi threading? If you can help me out with some working ex., I will obviously increase points to 2 or 3 times.

The actual code I'm using is as follows ...

type
   TDownloadManager = Class
      FtpClient1: TFtpClient;


  private
    { Private declarations }


...... functions and procedured ......

constructor TDownloadManager.Create();
begin
   FTPClient1:= TFTPClient.Create(nil);
   FTPClient1.OnProgress := FtpClient1Progress;
   FtpClient1.OnRequestDone:= FtpClient1RequestDone;
   FtpClient1.MultiThreaded:= True;
   fsize:= -1;
   byte_cnt:= 0;
   dir_Q:= TStringList.Create;
   //busy:= False;

end;

procedure TDownloadManager.uploadFile(self_idx, list_idx:integer; r_base_folder, r_file, L_file, proxy_host, proxy_port, proxy_usr, proxy_pwd, host, port, usr, PWord: String);
var
   p: integer;
   tmp, tmp2: String;
begin

  self_id:= self_idx;
  task_id:= list_idx;

.....

end;

after calling constructor to create an instance of this class, i'm using uploadFile function to upload files.
Now how can I make this in a seprate thread? Also when doing this through indy sync, will it not choke the app till the component gets response from the FTP server?

Plz guide me how can I port this code into threads?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7111952
one more thing ... that might be of some help for u
I'm using an array to store multiple instances of the class ... i.e.
DLoad_Manager: array[0..MAX_THREADS] of TDownloadManager;
and then calling its constructor ...
DLoad_Manager[i]:= TDownloadManager.Create;
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7112407
you should store the new threads in a TThreadList
to acces the threads do :
with ThdList.LockList do
try
  for I:=0 to Count-1 do
    TDownloadThread(Items[I]).DoStuff;
finally
  ThdList.UnlockList;
end;

here's the basics to the TDownloadThread
just came home from a club so I'm a bit tired to write the whole thing
if needed I'll write it, but not now :)


-----------------------------


unit Unit2;

interface

uses
  Classes, SysUtils, IdFTP;

type
  TDownloadThread = class(TThread)
  private
    FTP: TIdFTP;
    FLocal,
    FRemote: string;
    FMode: Integer;
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure UploadFile(self_idx, list_idx:integer; r_base_folder, r_file,
      L_file, proxy_host, proxy_port, proxy_usr, proxy_pwd, host, port, usr, PWord: String);
  end;

implementation


constructor TDownloadThread.Create;
begin
     inherited Create(true);
     FreeOnTerminate:=true;
     FTP:=TIdFTP.Create(nil);
end;

destructor TDownloadThread.Destroy;
begin
     FreeAndNil(FTP);
     inherited;
end;

procedure TDownloadThread.Execute;
begin
     FTP.Connect;
     if not FTP.Connected then exit;
     if FMode = 1 then
        FTP.Put(FLocal, FRemote, false)
     else
        FTP.Get(FRemote, FLocal, true, false);

     FTP.Disconnect;
end;

procedure TDownloadThread.UploadFile(self_idx, list_idx: integer;
  r_base_folder, r_file, L_file, proxy_host, proxy_port, proxy_usr,
  proxy_pwd, host, port, usr, PWord: String);
begin
     FTP.Host:=host;
     FTP.Port:=StrToIntDef(port, 21);
     FTP.Username:=usr;
     FTP.Password:=PWord;
     FLocal:=L_file;
     FRemote:=r_File;
     FMode:=1; // indicate that we're uploading
     // set all the other properties, also some progress events
     Resume; // start the thread
end;

// procedure for downloading would be similar, only set the FMode to 0 or something ...

end.
0
 
LVL 1

Expert Comment

by:VENKAT
ID: 7112671
You can try Delphi component-IntenetMailSuite-agFTP or Fastnet NMFTP components.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7113104
fastnet ??? hey you crazy ?
nobody that has a clear mind uses NM ! .. and for a good reason too
especially their ftp component
it has support for only one list format and it parses that one badly also !
not to mention other things ...
0
 
LVL 1

Author Comment

by:m_adil
ID: 7113171
yeah ... NM is useless...

Lee can u plz help in adding a thread in ThreadList.

should it be like...

//create thread
DLoad_Manager[i]:= TDownloadManager.Create;
List.Add(DLoad_Manager[i]);

where list is TThreadList.
0
 
LVL 1

Author Comment

by:m_adil
ID: 7113246
I've tried it as follows .... and its working fine.
but i just want to make sure that there isn't any problem in this code and it will work fine.

with Thread_List.LockList do
try
   DLoad_Manager[thread_idx].uploadFile(thread_idx, new_task_id, RemoteFrm.cbo_Remote_Dir.Text, remote_file, local_file, proxy_host, proxy_port, proxy_usr, proxy_pwd, host, usr, pwd, port);

finally
      Thread_List.UnlockList;
end;
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7113552
you don't need a second array if you're using a ThreadList
and if you don't plan to do anything with the thread later on then there's also no need to store the threads in the list
so if you simply need to download some files then do:

procedure TForm1.UploadFile(...);
var dlThread: TDownloadThread;
begin
  dlThread:=TDownloadThread.Create;
  dlThread.UploadFile(...);
end;

the thread will be freed when it terminates
you also don't need to worry about dlThread coz it will be released when the function exists

so in this case you really don't need any lists


if you make your threads reusable then store them in the list
also don't forget to set the FreeOnTerminate:=false; in the constructor !!!
you should also change the execution method
take a look at my TlnThread base class:
http://lee.nover.has.his.evilside.org/isapi/pas2html.dll/pas2html?File=/delphi/MiscFiles/vn_common/lnVidTypes.pas

reusable threads really not needed in your case unless you tend to upload multiple files at once and all the time (like 100 files all the time)

if you go for the reusable threads I'll guide you further more :))
0
 
LVL 1

Author Comment

by:m_adil
ID: 7115664
Lee ... I surely want to reuse threads as there is not a fixed no of files that I've to upload/download. It could be any no (100, 1000...) so i've to reuse threads.
So I'll definately welcome your guidance in this matter :)

I'm increasing points to 100. will further increase as we get into it further.
0
 
LVL 1

Author Comment

by:m_adil
ID: 7118075
Lee I've tried it but the thread after finishing one take does not start the next task. Is it because the thread is already in running state and Resume call doesnot make any changes in this state. Do I need to change its state first or what ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7118122
Lee I've tried it but the thread after finishing one take does not start the next task. Is it because the thread is already in running state and Resume call doesnot make any changes in this state. Do I need to change its state first or what ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7118149
Lee I've tried it but the thread after finishing one take does not start the next task. Is it because the thread is already in running state and Resume call doesnot make any changes in this state. Do I need to change its state first or what ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7118192
Lee I've tried it but the thread after finishing one take does not start the next task. Is it because the thread is already in running state and Resume call doesnot make any changes in this state. Do I need to change its state first or what ?
0
 
LVL 1

Author Comment

by:m_adil
ID: 7118211
Lee I've tried it but the thread after finishing one take does not start the next task. Is it because the thread is already in running state and Resume call doesnot make any changes in this state. Do I need to change its state first or what ?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7118310
damn it dood .. what are you doing ?

did you take a look at the link I gave you ?
the TlnThread class has a .Run method which you need to override
in the run method you execute your upload
when you're done uploading simply call Stop;
I'll write a new descendant for you in a while
0
 
LVL 1

Author Comment

by:m_adil
ID: 7121938
>> I'll write a new descendant for you in a while
when will u be able to do this ?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7122107
today later on - hang on
0
 
LVL 1

Author Comment

by:m_adil
ID: 7130062
I'll wait for your reply for another 12 hrs and will reopen the question in case u do not reply.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7130760
oh sorry
I'm just so busy
here .. writing it now :)
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 100 total points
ID: 7130832
ok this should work
the syntax is ok but I haven't tested if it works
it's just to demonstrate how it should be done with queuing the commands
here's the complete unit code:


unit Unit2;

interface

uses Windows, Classes, SysUtils, lnVidTypes, idFTP;

type
  TOperation = (opDownload, opUpload);

  PFtpInfo = ^TFtpInfo;
  TFtpInfo = packed record
    Host: string[255];
    Port: Word;
    User: string[32];
    Pass: string[32];
    Passive: Boolean;
  end;

  POperationInfo = ^TOperationInfo;
  TOperationInfo = packed record
    Operation: TOperation;
    LocalFile: string[255];
    RemoteFile: string[255];
    FtpInfo: TFtpInfo;
  end;

  TlnFTPThread = class(TlnThread)
  private
    FQueue: TList;
    FFTP: TidFTP;
  protected
    procedure Run; override;
  public
    constructor Create(Suspended: Boolean);
    destructor Destroy; override;
    procedure QueueFile(OperationInfo: TOperationInfo);
  end;


implementation



{ TlnFTPThread }

constructor TlnFTPThread.Create(Suspended: Boolean);
begin
     inherited Create(Suspended);
     FQueue:=TList.Create;
     FFTP:=TidFTP.Create(nil);
end;

destructor TlnFTPThread.Destroy;
var lpOI: POperationInfo;
    I: Integer;
begin
     if FQueue.Count > 0 then
        for I:=FQueue.Count-1 downto 0 do
            try
               lpOI:=FQueue.Items[I];
               Dispose(lpOI);
            except
            end;

     FreeAndNil(FQueue);
     if FFTP.Connected then
        FFTP.Disconnect;
     FreeAndNil(FFTP);
end;

procedure TlnFTPThread.QueueFile(OperationInfo: TOperationInfo);
var lpOI: POperationInfo;
begin
     New(lpOI);
     lpOI^:=OperationInfo;
     FQueue.Add(lpOI);
     Start;
end;

procedure TlnFTPThread.Run;
var lpOI: POperationInfo;
begin
     if FQueue.Count < 1 then exit;

     lpOI:=FQueue.Items[0];
     try
        try
           if FFTP.Connected then
              FFTP.Disconnect;

           FFTP.Host:=lpOI^.FtpInfo.Host;
           FFTP.Port:=lpOI^.FtpInfo.Port;
           FFTP.Username:=lpOI^.FtpInfo.User;
           FFTP.Password:=lpOI^.FtpInfo.Pass;
           FFTP.Passive:=lpOI^.FtpInfo.Passive;
           FFTP.Connect(true, 5000); // give it 5 secs to connect

           case lpOI^.Operation of
             opDownload:
             begin
               FFTP.Get(lpOI^.RemoteFile, lpOI^.LocalFile);
             end;

             opUpload:
             begin
               FFTP.Put(lpOI^.LocalFile, lpOI^.RemoteFile);
             end;
           end;

           DoNotifyWait(1, 1); // just notify of success, change this to your needs :)

        except
           on E: Exception do // failed to connect, upload, ...
              DoNotifyWait(0, Integer(PChar(E.Message)));
        end;
     finally
        Dispose(lpOI);
        FQueue.Delete(0);

        if FFTP.Connected then
           FFTP.Disconnect;
     end;
end;

end.
0
 

Expert Comment

by:CleanupPing
ID: 9343157
m_adil:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
LVL 22

Expert Comment

by:mnasman
ID: 9388068
points to Lee_Nover
0
 
LVL 5

Expert Comment

by:Lukasz Lach
ID: 9453969
m_adil,
No comment has been added lately (11 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: Award points to Lee_Nover http:#7112407

Please leave any comments here within 7 days.

-- Please DO NOT accept this comment as an answer ! --

Thanks,

anAKiN
EE Cleanup Volunteer
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now