Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Indy 9 TIdFTP EIdConnClosedGracefully etc.... (repost)

356 views
Skip to first unread message

Skaarak

unread,
Aug 9, 2006, 12:07:18 PM8/9/06
to
Very sorry for the repost, but what I posted on my home
news server doesn't seem to be making it to the borland.com
newsgroup.
-------------------------------------------------------------------------

Borland 6, Indy 9.0.50 (upgraded from 8... probably a mistake)

TIdFTP FTP2;
TListBox RawDir;

Code looks roughly:

FTP2->Connect(true, 5000);
//if connected
FTP2->ChangeDir("AddOns");
FTP2->List(RawDir->Items, "*", true);

When I hit the list command I get the EidConnClosedGracefully exception.

If I try to step past it I just keep getting the error. If I ignore the
exceptions
(Tools->Debugger....) the program just hangs.

This was working great in version 8. Any ideas?

-Cory


Remy Lebeau (TeamB)

unread,
Aug 9, 2006, 12:23:02 PM8/9/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44da0822$1...@newsgroups.borland.com...

> FTP2->List(RawDir->Items, "*", true);
>
> When I hit the list command I get the EidConnClosedGracefully exception.

As you should be. The FTP protocol uses a secondary connection for data
transfers and directory listings. You are simply seeing the exception that
is generated when the server closes that second connection. List() will
catch that exception internally. It will not reach your own code. Since
you are running your code inside the IDE debugger, the debugger will see all
exceptions. Simply press F9 to pass the exception back to the project for
normal handling. You should also add EIdSilentException (which
EIdConnClosedGracefully derives from) to your debugger's list of exceptions
to ignore.


Gambit


Skaarak

unread,
Aug 9, 2006, 5:24:34 PM8/9/06
to
"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:44da0c3a$1...@newsgroups.borland.com...

Ah Gambit, my favorite debugger. =)
So, adding EIdSilentException to my debugger list stops the
EIdConnClosedGracefully
exceptions. (What's F9? I've remapped my IDE)

But even after stopping the exceptions the FTP->List() command just hangs.
No
time out, no error, just hangs. Its odd. As per my last message, it worked
in
version 8, but not in 9. Any thoughts?

-Cory


Remy Lebeau (TeamB)

unread,
Aug 9, 2006, 6:09:56 PM8/9/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44da...@newsgroups.borland.com...

> What's F9? I've remapped my IDE

It is the "Run" command.

> But even after stopping the exceptions the FTP->List() command just hangs.

Did you apply the TIdTCPConnection::ReadStream() fix that I have described
in other discussions? For example, have a look at the "Trouble with the
Last Indy9v with the CB6 vs. old Indy9" discussion from a few days ago in
this same newsgroup.


Gambit


Skaarak

unread,
Aug 9, 2006, 7:13:43 PM8/9/06
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:44da5f29$1...@newsgroups.borland.com...

Ah, very nice. Okay, I went in, applied the fix, recompiled the Indy
products
and re-ran my program.

No it no longer sticks on that point, but it just puts forth a dialog box
(with
red x icon) that says "Connection Closed Gracefully".
It also seems to stop any further progress into my function. I step to that
spot,
the dialog pops up (not an exception as I have them ignored) and even after
hitting okay on the dialog my IDE never comes back to my debug spot.

The program integrity seems to be okay (I can close it, move it, etc) but it
just wont continue?

-Cory


Remy Lebeau (TeamB)

unread,
Aug 9, 2006, 8:08:39 PM8/9/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44da6c13$1...@newsgroups.borland.com...

> No it no longer sticks on that point, but it just puts forth a dialog
> box (with red x icon) that says "Connection Closed Gracefully".

Are you still running inside the debugger at the time?

> It also seems to stop any further progress into my function. I step to
that
> spot,
> the dialog pops up (not an exception as I have them ignored) and even
after
> hitting okay on the dialog my IDE never comes back to my debug spot.

If you are inside the debugger, did you press the Run command after the
dialog was closed? When the debugger breaks on an exception, it will not
continue execution of the program until you explicitally tell it to do so.


Gambit


Skaarak

unread,
Aug 10, 2006, 6:59:20 PM8/10/06
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:44da...@newsgroups.borland.com...

Still in the debugger, and even hitting 'Run' after closing the dialog box
(not an exception box, a program pop-up) does not cause it to continue.

-Cory


Remy Lebeau (TeamB)

unread,
Aug 10, 2006, 8:12:24 PM8/10/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44dbb9a3$1...@newsgroups.borland.com...

> Still in the debugger, and even hitting 'Run' after closing the dialog box
> (not an exception box, a program pop-up) does not cause it to continue.

There are no popup messages in Indy. "Connection Closed Gracefully" is an
exception message. If you are not seeing the debugger display an exception
popup for it, then your program has to be showing its own popup message,
such as in an exception handler. Or you are not catching any exceptions and
they are falling through to the VCL's default handler.

Please show your actual code. List() should not be throwing an "Connection
Closed Gracefully" exception, even with the ReadStream() fix applied.


Gambit


Skaarak

unread,
Aug 11, 2006, 11:29:59 AM8/11/06
to
"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:44dbcbbb$1...@newsgroups.borland.com...

Below are the "basics". FTP2 is the TldFTP program. It calls the
parsedirectory
function and that's what fails. I've included the FormCreate function as
well
so you can see what's in it. The SaveLoad() just reads values from regestry
and puts them into a couple of edit boxes (unrelaed).
Stepping through the code I get to this line FTP2->List(RawDir->Items,"*",
true);
int the ParseDirectory function before it fails and throws the Dialog Box.
-Cory

//---------------------------------------------------------------------------
void __fastcall TForm1::ConnectClick(TObject *Sender)
{
int i;
TStringList *names;
if (!FTP2->Connected()) {
FTP2->Host = Server->Text;
FTP2->Username = UserName->Text;
FTP2->Password = AdminForm->Decode(Password->Text);
FTP2->Connect(true, 5000);

if (FTP2->Connected()) {
names = new TStringList ();
FTP2->ChangeDir("AddOns");
ParseDirectory (names, NULL, NULL, true);
RemoteDir->Items = names;
delete names;
}
}
}

//---------------------------------------------------------------------------
void __fastcall TForm1::ParseDirectory(TStringList *name, TStringList
*directory, TStringList *size, bool dironly)
{
int i;
bool dir;
AnsiString temp;
RawDir->Clear();


FTP2->List(RawDir->Items,"*", true);

for (i=0; i<RawDir->Count; i++) {
dir = false;
temp = RawDir->Items->Strings[i].SubString(0,10); //directory //0
based I think (Index , COunt)
if (temp.c_str()[0] == 'd' || temp.c_str()[0] == 'D') {
dir = true;
}
if (directory != NULL) {
if (dir || (!dironly)) {
directory->Add(temp);
}
}
temp = RawDir->Items->Strings[i].SubString(11,16); //Unknown
temp = RawDir->Items->Strings[i].SubString(27,16); //Size
if (size != NULL) {
if (dir || (!dironly)) {
size->Add(temp);
}
}
temp = RawDir->Items->Strings[i].SubString(44,12); //Date
temp = RawDir->Items->Strings[i].SubString(57,99); //Name
if (name != NULL) {
if (dir || (!dironly)) {
name->Add(temp);
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
AnsiString temp;
this->Left = 100;
this->Top = 100;
this->ClientWidth = 800;
this->ClientHeight = 600;

temp.printf("Interface Assistant v%d.%02d.%02d", MAJOR_VERSION,
MINOR_VERSION, VER_REV);
Form1->Caption = temp;

CurFile->Caption = "";
Size->Caption = "";
dt = NULL;

SaveLoad (ID_LOAD);
}


Remy Lebeau (TeamB)

unread,
Aug 11, 2006, 2:06:19 PM8/11/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44dc...@newsgroups.borland.com...

> I've included the FormCreate function as well so you can see what's in it.

DO NOT use the OnCreate event in C++! It is a Delphi idiom that produces
illegal behavior in C++ as it can be triggered before the constructor. Use
the actual constructor instead.

> Stepping through the code I get to this line FTP2->List(RawDir->Items,"*",
> true); int the ParseDirectory function before it fails and throws the
Dialog Box.

Did you try putting try..catch blocks into your code yet?

__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{


this->Left = 100;
this->Top = 100;
this->ClientWidth = 800;
this->ClientHeight = 600;

AnsiString temp;


temp.printf("Interface Assistant v%d.%02d.%02d", MAJOR_VERSION,
MINOR_VERSION, VER_REV);

this->Caption = temp;

CurFile->Caption = "";
Size->Caption = "";
dt = NULL;

SaveLoad (ID_LOAD);
}

void __fastcall TForm1::ConnectClick(TObject *Sender)
{
if( !FTP2->Connected() )


{
FTP2->Host = Server->Text;
FTP2->Username = UserName->Text;
FTP2->Password = AdminForm->Decode(Password->Text);

try
{
FTP2->Connect(true, 5000);
try
{
FTP2->ChangeDir("AddOns");
if( !ParseDirectory(RemoteDir->Items, NULL, NULL,
true) )
ShowMessage("Parse Directory Error");
}
catch(const Exception &)
{
FTP2->Disconnect();
throw;
}
}
catch(const Exception &e)
{
ShowMessage(e.Message);
}
}
}

bool __fastcall TForm1::ParseDirectory(TStrings *name, TStrings
*directory, TStrings *size, bool dironly)
{
bool dir;
AnsiString item, temp;
RawDir->Clear();

try
{


FTP2->List(RawDir->Items,"*", true);
}

catch(const Exception &)
{
return false;
}

for(int i = 0; i < RawDir->Count; ++i)
{
dir = false;
item = RawDir->Items->Strings[i];

temp = item.SubString(1, 10); //directory
if( (temp != "") && ((temp[1] == 'd') || (temp[1] == 'D')) )
dir = true;
if( (directory) && ((dir) || (!dironly)) )
directory->Add(temp);

temp = item.SubString(11, 16); //Unknown

temp = item.SubString(27, 16); //Size
if( (size) && ((dir) || (!dironly)) )
size->Add(temp);

temp = item.SubString(44, 12); //Date

temp = item.SubString(57, 99); //Name
if( (name) && ((dir) || (!dironly)) )
name->Add(temp);
}

return true;
}


Gambit


Skaarak

unread,
Aug 11, 2006, 3:29:30 PM8/11/06
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:44dcc77f$1...@newsgroups.borland.com...

>
> "Skaarak" <ska...@NOakamailSPAM.com> wrote in message
> news:44dc...@newsgroups.borland.com...
>
>> I've included the FormCreate function as well so you can see what's in
>> it.
>
> DO NOT use the OnCreate event in C++! It is a Delphi idiom that produces
> illegal behavior in C++ as it can be triggered before the constructor.
> Use
> the actual constructor instead.
>
>> Stepping through the code I get to this line
>> FTP2->List(RawDir->Items,"*",
>> true); int the ParseDirectory function before it fails and throws the
> Dialog Box.
>
> Did you try putting try..catch blocks into your code yet?

Okay, put in the try/catch block where located, and the FTP2->List command
catchs an exception and my function ends.

No idea what to do next, doesn't do me any good if List just fails.

Move all items out of the "OnCreate" event into the constructor

-Cory
ps. Is there any way to go from Indy 9 to 8 easily?


Remy Lebeau (TeamB)

unread,
Aug 11, 2006, 6:41:42 PM8/11/06
to

"Skaarak" <ska...@NOakamailSPAM.com> wrote in message
news:44dcd9f4$1...@newsgroups.borland.com...

> Okay, put in the try/catch block where located, and the FTP2->List
> command catchs an exception and my function ends.

EIdConnClosedGracefully is only thrown when a socket is directly accessed
after it has been closed by the other party, and even then only after the
TIdTCPConnection.InputBuffer property has been emptied or otherwise cannot
satisfy anymore read operations.

Remember that file transfers and directory listings use a second socket
connection. After applying the fix for ReadSteam() (which List() calls on
the second connection to download the listing data), the only remaining way
for List() to throw EIdConnClosedGracefully is if the main command
connection is being closed by the server, since ReadStream() will catch and
discard the EIdConnClosedGracefully on the second data connection in this
situation.

> Is there any way to go from Indy 9 to 8 easily?

No.


Gambit


0 new messages