Thread View: borland.public.cppbuilder.internet.socket
9 messages
9 total messages
Started by Lesley Anne
Wed, 23 Aug 2006 18:27
Indy 9 TIdFTP Client - when is a Put() finished?
Author: Lesley Anne
Date: Wed, 23 Aug 2006 18:27
Date: Wed, 23 Aug 2006 18:27
6 lines
1268 bytes
1268 bytes
I'm trying to implement an FTP Client that uploads files to a server, but then I want it to move my local copy of the file to another directory once the transfer is finished. If I were pulling rather than pushing, the TIdFTP component has an OnAferGet event, but there doesn't seem to be a corresponding OnAfterPut event. How can I tell when the transfer is complete?
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Remy Lebeau (TeamB)
Date: Wed, 23 Aug 2006 19:56
Date: Wed, 23 Aug 2006 19:56
18 lines
1469 bytes
1469 bytes
"Lesley Anne" <mspfila-ng@yahoo.com> wrote in message news:44ec9e0a@newsgroups.borland.com... > If I were pulling rather than pushing, the TIdFTP component > has an OnAferGet event, but there doesn't seem to be a > corresponding OnAfterPut event. Indy is not an event-driven library. You don't need to use the OnAfterGet event. Like everything else in Indy, Get() and Put() are blocking functions. They do not exit until their work is finished. > How can I tell when the transfer is complete? When Put() exits. Gambit
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Lesley Anne
Date: Wed, 23 Aug 2006 21:01
Date: Wed, 23 Aug 2006 21:01
18 lines
1856 bytes
1856 bytes
> Indy is not an event-driven library. You don't need to use > the OnAfterGet event. Like everything else in Indy, Get() > and Put() are blocking functions. They do not exit until > their work is finished. > > > How can I tell when the transfer is complete? > > When Put() exits. Oh, good. That makes it easier than I thought. (Sorry if it was a dumb question. I haven't worked with the Indy library very much. So far I'm liking it, but I'm not really used to it yet. It organizes things a lot differently than the TurboPower library that I've worked with before.) So if the current function is going to remain at this call throughout the file transfer, does that mean it's designed to be put into its own thread, or does Put() contain provisions for making sure that the Windows Message queue will keep being processed as necessary?
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Remy Lebeau (TeamB)
Date: Wed, 23 Aug 2006 22:28
Date: Wed, 23 Aug 2006 22:28
17 lines
1442 bytes
1442 bytes
"Lesley Anne" <mspfila-ng@yahoo.com> wrote in message news:44ecc221$1@newsgroups.borland.com... > So if the current function is going to remain at this call throughout > the file transfer, does that mean it's designed to be put into its > own thread Indy works well in threads, but threading is not strictly required. > does Put() contain provisions for making sure that the Windows > Message queue will keep being processed as necessary? You have to use a TIdAntiFreeze component for that. Gambit
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Lesley Anne
Date: Thu, 24 Aug 2006 15:44
Date: Thu, 24 Aug 2006 15:44
20 lines
2031 bytes
2031 bytes
> Indy works well in threads, but threading is not > strictly required. > > > does Put() contain provisions for making sure that > > the Windows Message queue will keep being processed > > as necessary? > > You have to use a TIdAntiFreeze component for that. The help file's pages on TIdAntiFreeze are a little confusing (and it doesn't seem to be used in any of the demos I have). Does it just need to be present on the form and Active, or do I need to explicitly call its Process or DoProcess functions (in which case where would those calls go in relation to IdFTP1->Put()). Are there any advantages/disadvantages that I should know about in the decision as to whether to use the TIdAntiFreeze component or whether to separate FTP processing into a separate thread? (The application does have other tasks unrelated to FTP, and sometimes the files to be FTP'd could be fairly large - if either of those facts makes a difference.)
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Remy Lebeau (TeamB)
Date: Thu, 24 Aug 2006 16:50
Date: Thu, 24 Aug 2006 16:50
29 lines
1994 bytes
1994 bytes
"Lesley Anne" <mspfila-ng@yahoo.com> wrote in message news:44edc970$1@newsgroups.borland.com... > Does it just need to be present on the form and Active Yes. > do I need to explicitly call its Process or DoProcess functions No. Indy calls them automatically when needed. > Are there any advantages/disadvantages that I should know about > in the decision as to whether to use the TIdAntiFreeze component > or whether to separate FTP processing into a separate thread? TIdAntiFreeze calls Application->ProcessMessages() regularly during a blocking operation. That can have performance issues, as well as introduce possible reentrant problems in your event handlers if you are not careful. > The application does have other tasks unrelated to FTP, and > sometimes the files to be FTP'd could be fairly large - if either of > those facts makes a difference. Lengthy operations tend to work better in general when they are moved outside of the main thread. Gambit
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Lesley Anne
Date: Thu, 24 Aug 2006 17:31
Date: Thu, 24 Aug 2006 17:31
20 lines
2136 bytes
2136 bytes
> TIdAntiFreeze calls Application->ProcessMessages() regularly during > a blocking operation. That can have performance issues, as well as > introduce possible reentrant problems in your event handlers if you > are not careful. ... > Lengthy operations tend to work better in general when they are > moved outside of the main thread. All right. I'll make a separate thread for it then. Although I think I should be able to take care of reentry problems by just turning off the timer that gets me into this section, I'd rather not introduce any performance problems. Luckily I've got the FTP related code fairly well isolated from the other tasks my application is doing, so that should make moving it to another thread easier. I want to thank you for all the help you've been in figuring out how this works. I'll get the hang of working with Indy and blocking sockets in time, and all the faster for having someone as knowledgeable as yourself being willing to take the time to explain it so clearly. You've been a great help. Thanks.
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Lesley Anne
Date: Thu, 24 Aug 2006 22:59
Date: Thu, 24 Aug 2006 22:59
129 lines
5799 bytes
5799 bytes
Well, I've got my IdFTP client moved off to its own thread. You mentioned
earlier about Indy not being an event-driven library, but it does include
some events and I'm still a little confused on when, whether, and how to use
them.
It looks as though the Connect() method should include logging in to the
server so long as I don't override its default value for AAutoLogin, but
then there's also the component's OnAfterClientLogin and OnStatus events.
Do I need to look for the occurance of those event triggers, or can I trust
that if Connect() returned without throwing any exceptions then I should be
ready to send files?
If I do need to wait for events, I'm not really sure how to do that within a
secondary thread. When I'm working in the application's main thread, if I
need a function to wait for an event to trigger before continuing, I use
something of the form:
while (condition) Application->ProcessMessages;
and then make the event handler set the condition. I'm not sure what the
equivalent is in a secondary thread, though. I don't want it to deal with
the application's main message queue, but with its own message queue.
(Though if the answer to my first question was that I don't need to deal
with the events, that would make this issue irrelevant.)
Well, I'm still not sure whether I have the solution structured correctly,
but this is what my thread code looks like so far:
// ------------------------------------------------------------------
__fastcall TFTPThread::TFTPThread(const AnsiString &pFileNameMask,
const AnsiString &pFinishedDir,
const AnsiString &pHostAddress,
int pHostPort,
const AnsiString &pUsername,
const AnsiString &pPassword)
: TThread(true)
{
// Set thread properties
Priority = tpNormal;
FreeOnTerminate = true;
// Set input parameters
FileNameMask = pFileNameMask;
FinishedDirectory = pFinishedDir;
HostAddress = pHostAddress;
HostPort = pHostPort;
Username = pUsername;
Password = pPassword;
}
// ------------------------------------------------------------------
void __fastcall TFTPThread::AfterConstruction()
{
Resume();
}
// ------------------------------------------------------------------
void __fastcall TFTPThread::Execute()
{
TIdFTP *IdFTP;
TSearchRec sr;
String SendDirectory = ExtractFilePath(FileNameMask);
// initialize output fields
FilesSent = new TStringList;
Success = true;
AppMessage = "";
// check for files to send
if (FindFirst(FileNameMask, 0, sr) == 0) {
try {
// set up FTP component
IdFTP = new TIdFTP(NULL);
IdFTP->Host = HostAddress;
IdFTP->Port = HostPort;
IdFTP->Username = Username;
IdFTP->Password = Password;
IdFTP->ProxySettings->ProxyType = fpcmNone;
// Connect to host
try {
IdFTP->Connect();
} catch (...) {
Success = false;
AppMessage = "ERROR: Could not connect to FTP Host";
}
// Send files
if (Success) {
do {
// Send file
try {
IdFTP->Put(SendDirectory + sr.Name, sr.Name, false);
} catch (...) {
Success = false;
AppMessage = "ERROR: failed to transfer " +
sr.Name + " to FTP Host";
}
// move local file
if (Success) {
if (RenameFile(SendDirectory + sr.Name,
FinishedDirectory + sr.Name)) {
FilesSent->Add(sr.Name);
} else {
Success = false;
AppMessage = "ERROR: unable to move " +
sr.Name + " to " + FinishedDirectory;
}
}
} while (Success && (FindNext(sr) == 0));
IdFTP->Disconnect();
}
} __finally {
FindClose(sr);
delete IdFTP;
}
}
// Send results back to main application thread
Synchronize(ReturnResult);
delete FilesSent;
}
// ------------------------------------------------------------------
void __fastcall TFTPThread::ReturnResult()
{
MainForm->HandleFTPResult(Success, FilesSent, AppMessage);
}
// ------------------------------------------------------------------
Re: Indy 9 TIdFTP Client - when is a Put() finished?
Author: Remy Lebeau (TeamB)
Date: Thu, 24 Aug 2006 23:23
Date: Thu, 24 Aug 2006 23:23
56 lines
3305 bytes
3305 bytes
"Lesley Anne" <mspfila-ng@yahoo.com> wrote in message
news:44ee2f56$1@newsgroups.borland.com...
> You mentioned earlier about Indy not being an event-driven library,
> but it does include some events and I'm still a little confused on when,
> whether, and how to use them.
Most of Indy's events are only for reporting statuses. Most of Indy's
functionality does not depend on using events. There are, of course, some
exceptions to that rule where necessary. But for the most part, Indy is a
very straight-forward, synchronous, serialized library.
> It looks as though the Connect() method should include logging in to the
> server so long as I don't override its default value for AAutoLogin, but
> then there's also the component's OnAfterClientLogin and OnStatus events.
When AAutoLogin is True, Connect() may perform quite a number of operation
internally when setting up the connection with an FTP server. Sending the
username/password is the first step of that process. OnAfterClientLogin is
only used when AAutoLogin is True, to allow the user to do other things in
his/her own code after the username/password are accepted but before the
rest of the connection settings are established. When AAutoLogin is False,
the user has to call Login() manually, and OnAfterClientLogin is not used.
OnStatus is just very generic event for reporting textual messages about the
current state of the underlying socket.
> Do I need to look for the occurance of those event triggers
No.
> can I trust that if Connect() returned without throwing any exceptions
> then I should be ready to send files?
Yes.
> I don't want it to deal with the application's main message queue,
> but with its own message queue.
Secondary threads do not have any message queue by default. If you need a
message queue (which Indy does not), then you have to implement one in your
own code.
> // Connect to host
> try {
> IdFTP->Connect();
> } catch (...) {
Don't use '...' to cahtch VCL exceptions. Catch them by class type
explicitally instead:
} catch (const Exception &) {
Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads