0

I'm trying to connect to a FTP server from my Android app, all works correctly if there is no exception, but if I get a timeout the Android app just closes.

I did create a thread for the FTP connection, but still the same issue.

P.S if I compile it for Windows it works exactly as it should, and managing exceptions correctly.

The code for the FTP connection is :

  IdFTP1.ConnectTimeout := 1000;
  IdFTP1.Passive := True;
  IdFTP1.Host    := ftp_server;
  IdFTP1.Username:= ftp_user;
  IdFTP1.Password:= ftp_pass;
  if ftp_port<> '' then begin
    Try
      IdFTP1.Port    := StrToInt(ftp_port);
    except
      IdFTP1.Port := 21;
    End;
  end
  else
    IdFTP1.Port := 21;



  TTask.Run(
    procedure
    var
      ftp_error : Boolean;
    begin
      Try
        ftp_error := False;
        IdFTP1.Connect;
        IdFTP1.Passive := true;
        if ftp_folder= '' then
          IdFTP1.Put( System.IOUtils.TPath.Combine(System.IOUtils.tpath.getdocumentspath,'temp.txt'), ftp_file, False )
        else begin
          if ftp_folder[length(ftp_folder)] <> '/'  then
            ftp_folder:= ftp_folder+ '/';

          IdFTP1.Put( System.IOUtils.TPath.Combine(System.IOUtils.tpath.getdocumentspath,'temp.txt'), ftp_folder+ftp_file, False );
        end;
        IdFTP1.Disconnect;
      except
        ftp_error := True;
      End;
      TThread.Queue(nil,
        procedure
        begin
          if not ftp_error then begin

            showmessage('FTP connection correct');    
          end
          else begin
            showmessage('Error FTP');
          end;

        end);

    end);

This is the config of the IdFTP1 just in case something is wrong (if I don't mistake its all the default options though)

Just in case this is the config for IdFTP1 as DesignTime

Part 2 of config

This is the indy version we have installed right now:

Indy version just in case

Log File Update on Windows :

Stat Connected.
Recv 26/02/2019 9:51:03: 220-FileZilla Server 0.9.60 beta<EOL>220-written by Tim Kosse (tim.kosse@filezilla-project.org)<EOL>220 Please visit https://filezilla-project.org/<EOL>
Sent 26/02/2019 9:51:03: HOST [172.26.29.170]<EOL>
Recv 26/02/2019 9:51:03: 500 Syntax error, command unrecognized.<EOL>
Sent 26/02/2019 9:51:03: USER admin<EOL>
Recv 26/02/2019 9:51:03: 331 Password required for admin<EOL>
Sent 26/02/2019 9:51:03: PASS admin<EOL>
Recv 26/02/2019 9:51:03: 230 Logged on<EOL>
Sent 26/02/2019 9:51:03: FEAT<EOL>
Recv 26/02/2019 9:51:03: 211-Features:<EOL> MDTM<EOL> REST STREAM<EOL> SIZE<EOL> MLST type*;size*;modify*;<EOL> MLSD<EOL> UTF8<EOL> CLNT<EOL> MFMT<EOL> EPSV<EOL> EPRT<EOL>211 End<EOL>
Sent 26/02/2019 9:51:03: CLNT Indy 10.6.1.5182<EOL>
Recv 26/02/2019 9:51:03: 200 Don't care<EOL>
Sent 26/02/2019 9:51:03: TYPE I<EOL>
Recv 26/02/2019 9:51:03: 200 Type set to I<EOL>
Sent 26/02/2019 9:51:03: SYST<EOL>
Recv 26/02/2019 9:51:03: 215 UNIX emulated by FileZilla<EOL>
Sent 26/02/2019 9:51:03: TYPE I<EOL>
Recv 26/02/2019 9:51:03: 200 Type set to I<EOL>
Sent 26/02/2019 9:51:03: PASV<EOL>
Recv 26/02/2019 9:51:03: 227 Entering Passive Mode (172,26,29,170,232,171)<EOL>
Sent 26/02/2019 9:51:03: STOR camacho/p1<EOL>
Recv 26/02/2019 9:51:03: 150 Opening data channel for file upload to server of "/camacho/p1"<EOL>
Recv 26/02/2019 9:51:03: 226 Successfully transferred "/camacho/p1"<EOL>
Sent 26/02/2019 9:51:03: QUIT<EOL>
Recv 26/02/2019 9:51:03: 221 Goodbye<EOL>
Stat Disconnected.
halfer
  • 19,824
  • 17
  • 99
  • 186
vexen
  • 345
  • 1
  • 4
  • 20
  • "*I didnt create a thread for the FTP connection*" - yes you did, because you put it inside a `TTask` which runs in a thread that the RTL creates. I see nothing in the code that should not work on Android, though I do see a few things that could use some improvements (like adding a `try..finally` to always call `Disconnect` whether an exception is raised or not). – Remy Lebeau Feb 21 '19 at 15:31
  • @RemyLebeau Dont know why i said i didnt create a thread... was a mental lapsus. I did create a thread even more i tried 3 different threads, TTask, TThread and AnonymousThread and none work, i did try to strip the try except and let indy handle the exception but the result is the same, whenever i get an exception from connect it doesnt even let the timeout to pass, as it immedeatly closes the android app, im not sure if this is the correct way to make a worker thread for android but i didnt find other ways to create threads. – vexen Feb 21 '19 at 19:47
  • The only way an exception could close the app is if you are not catching the exception, letting it escape back into the OS. That should not be happening in this code, though. The worker thread you are calling `Connect()` in should be catching the exception internally if you don't catch it in your code. And besides, this is the first time I've heard of an exception closing the app immediately on Android (Delphi has known issues with exception handling on OSX, but not on Android, AFAIK). Are you sure it is even an exception being thrown? How do you know, if you can't catch it? – Remy Lebeau Feb 21 '19 at 21:22
  • That is the main problem, i dont know if its an exception or something more, but the thing is that the ftp.connect() is the code that closes the app, and i have no way to debug it more than what i see. I tried only ftp.Connect and it just closes the app on that only line and it doesnt matter if its inside a try .. except or anything else :/ im out of options rn.... gonna try it in delphi Tokyo to see if it makes any difference, but the problem is i dont have a valid license for tokyo... – vexen Feb 22 '19 at 09:16
  • P.S sorry i didnt know it was impolite to post in multiple platforms, usually i just use stack overflow, but yesterday found the new embarcadero forum and tried it aswell to see if more people get to answer. I didnt want to be impolite in any way. – vexen Feb 22 '19 at 09:22
  • Another thing, is it ok if the thread is in the main form? or do i have to make another unit with the thread? – vexen Feb 22 '19 at 09:25
  • I can't help with the connect crash without knowing more about what is actually happening, and I can't debug that myself right now. A thread doesn't care which unit it is declared in. Or it in whatever unit to want, that is just an organizational thing. – Remy Lebeau Feb 22 '19 at 16:30
  • I suppose you dont see anything wrong in the IdFTP configuration nor the Indy version is very old, tried to copy paste a code you corrected for another person in a question here on Stack Overflow and it still does the same.... So it has to be something internal for Indy it self? By the way there is no other component for FTP connection that would work in FMX for Android? i didnt find any. P.S tried on Android Version 9 and i think the other one was 8.1 both do the same thing – vexen Feb 22 '19 at 20:39
  • Well the code is ok for sure, just tried to compile a demo app with this code with Delphi 10.2 and it works as it should.... so its something in Delphi XE7 that doesnt work correctly.... Can it be something depending on the SDK of android? – vexen Feb 22 '19 at 22:29
  • No, I don't see anything wrong with the configuration. Yes, you are using a very old version of Indy (the current version is 10.6.2.5494). I can't comment on why `TIdFTP.Connect()` crashes in XE7 and not in 10.2, however `TIdFTP.Connect()` does a LOT of work internally, so it could literally be ANYTHING that is going wrong. I would suggest attaching one of the `TIdLog...` components to the `TIdFTP.Intercept` property and see how far it says `Connect()` is actually getting before it fails. Do you have the same problem if you use `TIdTCPClient` directly instead of `TIdFTP`? – Remy Lebeau Feb 23 '19 at 01:04
  • I wonder if you are encountering something [related to this issue](http://docwiki.embarcadero.com/RADStudio/en/Migrating_Delphi_Code_to_Mobile_from_Desktop#Use_a_Function_Call_in_a_try-except_Block_to_Prevent_Uncaught_Hardware_Exceptions), where Delphi's `except` actually *doesn't* catch ALL kinds of exceptions on Android (and Linux, and iOS) due to the way the LLVM backend generates code. See [Why the exception is not caught by the try… except end;?](https://stackoverflow.com/questions/52651931/). Maybe you are encountering an unexpected hardware exception, so it doesn't get caught correctly? – Remy Lebeau Feb 24 '19 at 03:03
  • Sorry for the late reply, ill try to add TIdLog and see what i can tell, later will try to update to latest indy version to see if that helps. And about the Hardware exception not being caught, that should only be a case when you dont call a Funcion or procedure if i understand correctly. That should not count to ftp.connect as its a procedure – vexen Feb 25 '19 at 07:49
  • Updated indy to 10.6.2.5494, still doesnt work... =( i never used TIdLog, any example on how to use that? – vexen Feb 25 '19 at 10:01
  • choose a logging component for your desired output (`TIdLogFile` for a log file, `TIdLogDebug` for debugger messages, `TIdLogEvent` for callback events, etc), configure it as needed and set its `Active` property to true, and assign it to the target component's `Intercept` property – Remy Lebeau Feb 26 '19 at 02:32
  • Added the log file i get on Windows in the question, but on android nothing is being written.... the file is there, but its just empty..... – vexen Feb 26 '19 at 08:59
  • will, then that means the crash is occurring before the socket attempts to connect to the server. Using the `TIdFTP.OnStatus` event, how far does it get? I imagine the crash happens after the `hsConnecting` status is reported, right? I'm sorry I can't be more helpful, but I have no way to debug this myself right now. Are you not able to step into Delphi's/Indy's source code with the debugger while running the app on Android to see exactly what is happening? – Remy Lebeau Feb 26 '19 at 16:16
  • For some reason debug doesn't work on my phone, will have to try that on a emulator, usually I don't use emulator cause if speed. Will give more info tomorrow – vexen Feb 27 '19 at 00:32
  • @RemyLebeau Sorry for being dumb and not knowing how to debug on my phone (Still not used to much to android developing), i solved that. Now i can see up to what point i get into ftp.connect. i get into TIdIOHandlerStack.ConnectClient; in IdIOHandlerStack and there i get to DoConnectTimeout(); and to LThread.WaitFor; (In my case line 283) which then calls into System.Classes inside the IF Defined(POSIX) if FExternalThread then this line gives exceptions : Socket Error #104 – vexen Mar 01 '19 at 10:02
  • P.S after i added back the IdLogFile and had a little more time debugging, now it stop on the same `TIdIOHandlerStack.ConnectClient` -> `DoConnectTimeOut` -> `if TIdAntiFreezeBase.ShouldUse then begin`and the exception is Socket Error #113 No Route to Host – vexen Mar 01 '19 at 12:09
  • that sounds like typical socket behavior when the client can't reach the server (though the particular lines of code you mention are not where the exceptions are actually raised, they are raised a few lines deeper). I'm more interested in what happens after that point to make your app exit. When the exception is raised, where does execution flow jump to next? Does the `except` block in your `TTask` get called? Does the exception propegate up the call stack until it escapes the `TTask`? Are there any internal exception handlers inside the RTL's source code getting called? – Remy Lebeau Mar 01 '19 at 16:02
  • That is the main problem, the try except doesn't get called, and debug just stops there even after I press continue after that I start getting exceptions like segment 13 and usual internal exception hexa code. The code doesn't even get there into the thread.queue part – vexen Mar 01 '19 at 20:04
  • Then I suggest you [file a bug report](https://quality.embarcadero.com) with Embarcadero, because this is becoming more of a Delphi RTL issue in regards to exception handling on Android, rather than an Indy issue (Indy is actually doing what it is supposed to be doing). Delphi already has issues with bad exception handling on OSX (which affects Indy), I hope they haven't now broken things on Android, too – Remy Lebeau Mar 01 '19 at 20:08
  • Will try that thanks, it's a pity I can't compile funcional app right now, will have to consider buying an upgrade to 10.3 I suppose. Thanks for the support. – vexen Mar 02 '19 at 08:05

0 Answers0