0 votes
by (120 points)

Hello,

I am using Rebex FTP/SSL for .NET Release 2014 R1.

Is there a way to reset the ftp state to "Disconnected"?

My application has scenarios whereby the WiFi signal will be lost occasionally, causing the FTP state machine to "hang" at the "Read" state. This prevents me for initiating another FTP upon the recovery of the WiFi signal.

If need, I can show you guys my source code. Please let me know.

Thanks,
Steve

Applies to: Rebex FTP/SSL

1 Answer

0 votes
by (148k points)

Hello, have you tried calling Ftp object's Disconnect() method?

by (120 points)
Hello Lukas,

Thank you for responding.  2 questions:

1.  What happens to the FTP state machine when the Wifi signal is disrupted during a FTP upload (as described in my scenario above)?

2.  What is the best practise or correct approach to handle such a scenario/exception?

Thank you,
Steve
by (120 points)
A third question...thanks :)

3.  Is it a small bug in the library I am using, which can be easily resolved via the latest library package?

Thanks,
Steve
by (148k points)
1) An exception is thrown, and the FTP state machine is left in whatever state it was at that point. This correspond to what you described above.

2) The recommended approach in this case is to dispose the Ftp object, create a new one, connect it again and retry the operation. This is preferred to calling the Disconnect method.

3) We don't consider this a bug. An Ftp object corresponds to a single FTP protocol session, and once that fails, it's the responsibility of the application to resolve that (usually by reconnecting and performing the operation again).
by (120 points)
Hello Lukas,

Thanks for the reply.

I have narrowed down my problem - For whatever reason, the lost of the WiFi signal did not raise an "ftp.upload" exception in my code (my understanding is that it will - from this thread -> http://forum.rebex.net/4873/sftp-problemdetected-upload-exception-handling ).  This is really strange.

I have attached the main parts of my code as follows.  If you could spare some time to have a look, maybe I made an error somewhere.

private void TransferLogFiles()
{
   if (ftp.State != FtpState.Disconnected)
      return;

    ftpWorker = new Thread(new ThreadStart(FtpWorkerThread));
    Extensions.SetThreadPriority(ftpWorker, (int)settings.Priorities.FTP);
    ftpWorker.IsBackground = true;
    ftpWorker.Start();
}

private void FtpWorkerThread()
{
   try
   {
      FileSet fileSet = new FileSet(settings.LogManager.TransferFolder);
      fileSet.Include("*.csv", TraversalMode.MatchFilesShallow);
      fileSet.Include("*.log", TraversalMode.MatchFilesShallow);
      fileSet.Include("*.hscsr", TraversalMode.MatchFilesShallow);

      LocalItemCollection files = fileSet.GetLocalItems();

      if (files.Count == 0)
         log.Warn("No files in transfer folder: Nothing to upload to FTP!");
      else
      {
         log.Info("Trying to connect to FTP server {0}:{1} with username \"{2}\" and password \"{3}\"", settings.LogManager.FTP.Address, settings.LogManager.FTP.Port, settings.LogManager.FTP.User, settings.LogManager.FTP.Password);
                        
         ftp.Timeout = settings.LogManager.FTP.Timeout * 1000;
         ftp.Connect(settings.LogManager.FTP.Address, settings.LogManager.FTP.Port);
         ftp.Login(settings.LogManager.FTP.User, settings.LogManager.FTP.Password);
         ftp.TransferMode = FtpTransferMode.Zlib;
         ftp.TransferType = FtpTransferType.Binary;
         if (!ftp.DirectoryExists(settings.LogManager.FTP.RemoteFolder))
            ftp.CreateDirectory(settings.LogManager.FTP.RemoteFolder);
        
         foreach (LocalItem file in files)
         {
            log.Info("Uploading \"{0}\" to FTP server", file.Name);
            ftp.Upload(file.FullPath, settings.LogManager.FTP.RemoteFolder, TraversalMode.MatchFilesShallow, Rebex.IO.TransferMethod.Copy, Rebex.IO.ActionOnExistingFiles.ResumeIfPossible);
                            
            MoveToBackup(file.FullPath);
         }
      }
   }
   catch (FtpException e)
   {
      log.Error("Error transferring files to FTP: \"{0}\"", e.Message);
   }
   finally
   {
      ftp.Disconnect();
   }
}
by (148k points)
Could you please use Ftp object's LogWriter property to create a communication/error log (as described at https://www.rebex.net/kb/logging/) and either post it here or mail it to us for analysis? That should make it possible to tell what exactly is going on inside Rebex FTP.
by (120 points)
Hello Lukas,

Please see requested logs at this dropboxlink ->https://www.dropbox.com/sh/tfko9lwr6iioqgo/AAB4wAfhaszfTaIKXfFiY2bOa?dl=0.

I have also included a simple log file (.log file - can be open as a text file) from my own application for reference.

Testing sequence as follows:
1. Power on application.
2. WiFi connection successful to router.
3. Wait 60 seconds, and application attempt to perform a FTP operation to filezilla server.
4. FTP connection successful and transfer initiates.
5.  In the middle of the transfer, I turn off the WiFi SSID, using another PC, causing WiFi signal to be lost.  This cause the FTP operation to cease.
6.  Wait for filezilla server to time out - 2 mins.
7. Turn back on the WiFi SSID.
8. Application auto reconnects back to the WiFi SSID, as it is now available.
9.  Attempt FTP operation again, but this time FTP state is "stuck" at "reading".  See application logs.

I am hopeful you can shed some light.

Thank you,
Steve
by (120 points)
Hello Lukas,

We notice that FTP throws System.Net.Sockets.SocketException.

However, I am unable to capture the exception, despite implementing (1) try /catch and (2) ftp event.

I attached a snippet of the FTP code in the same dropbox link (.cs file) for your reference.  Please have a look at the "FtpWorkerThread" method.

Thanks,
Steve
by (148k points)
Hello Steve,

- It looks like you are running your application on .NET Compact Framework, which we have not realized before. Which version of .NET CF do you use? Please try using the latest release (2018 R2) and let us know whether it still behaves the same.

- From the logs, it looks like Rebex FTP/SSL gets stuck inside the Upload method because the "finally" block in FtpWorkerThread never logs the "FtpDisconnect" message. This would explain why the Ftp object is stuck in "Reading" state. It's unclear whether this is a bug in Rebex FTP/SSL or in .NET Compact Framework, but calling ftp.Dispose() method from the foreground thread might be able to "unstuck" it, making FtpWorkerThread throw an exception.

- In FtpWorkerThread method, you only catch FtpException, but not any other kind. Adding "catch Exception" is recommended to make sure there are no unhandled exceptions.
by (120 points)
Hello Lukas,

I am using ,Net CF 3.5.  I am using WinCE 6.0.  Let me try your suggestions and will get back to you.

Thanks,
Steve
by (120 points)
Hello Lukas,

I managed to resolved the issue when (1) changing to catch "exceptions", instead of "ftpexceptions" and (2) using the latest Rebex FTP/SSL 2018 R2 release.

When using the Rebex FTP/SSL 2014 R2 release + catch "exceptions", it did not worked.

So it seems that the latest Rebex FTP/SSL 2018 R2 release fixed some earlier bugs.

I will do more testing and come back with a final confirmation.

Thanks,
Steve
by (148k points)
There have been lot of improvements since Rebex FTP/SSL 2014 R2 (see https://www.rebex.net/ftp-ssl.net/history.aspx#5298 for details).
It might be interesting to determine which release actually fixed this (I have not been able to identify any related change), but as the latest release works, it would not be an efficient use of time.
...