Hi all,

Sorry for not posting back sooner... I've been kinda busy lately...

I finally figured out how to solve the FTP abort problem I had, thanks to 
Daniel Savarese and to Martin Brunninger for their input...  They guided my on 
the right way!

First, I wrapped all my FTP code in a class.  Every Java class that wants to do 
FTP uses my class...

In my class, I use a monitor to synchronize thread access.  So every call to 
the FTPClient methods are wrapped in a synchronized(monitor) block.

Next, in my put and in my get methods, I use retrieveFileStream and 
storeFileStream and I pass the stream to a method which is responsible for 
transferring data between hosts.  I also store the thread that is doing the 
transfer so I can interrupt it later in my abort method.

In this transfer method, I check the Thread.currentThread().interrupted() flag 
to see if the transfer thread has been interrupted.  If it is interrupted, I 
call wait() on my monitor so I can abort the transfer properly.  This actually 
aborts the transfer on the client side.

Then, in my abort method, I first interrupt the transfer thread (to abort the 
transfer on the client side...), then, in my synchronized(monitor) block, I 
call the FTPClient.abort() mehtod.  This will actually abort the transfer from 
the server side.

Then, since both the client and the server are interrupted, I need to 
synchronize the response codes.  Remember from my original post that I got the 
426 for the file transfer first, and then the 226 response indicating that the 
abort command was successful.  Normally, the FTPClient class usually takes the 
426 for the abort, and the 226 for the transfer...

To trick the FTPClient class to process the return codes in the right order, I 
use a ProtocolCommandListener.  In the protocolCommandSent method, I first do a 
sleep(100) to give a chance to the server to process the abort command.  Then, 
I call monitor.notifyAll().  This will actually wake up the transfer thread 
that I put in wait mode when I started the abort process...  Then, I call 
monitor.wait(100) in the current thread to give the transfer thread a chance to 
process it's 426 code.  Remember that the transfer code is in a 
synchronized(monitor) block, so if I don't wait, the abort thread will get the 
426...

Finally, in the transfer thread, I just handle the transfer as usual by calling 
completePendingCommand()...

In the abort thread, since I called wait(100), the abort thread will wake up 
100 miliseconds later and it will process the 226 response code.

So, it's kind of a tricky way to handle the aborts, but it works fine!

I hope this helps someone, and, once again, thanks to Daniel and Martin who 
helped me solve this!

Cheers!!!

Ghis


 



-----Message d'origine-----
De : Ghislain Gadbois [mailto:[EMAIL PROTECTED]
Envoyé : 13 mars 2006 14:29
À : [email protected]
Objet : [Net]: FTPClient.abort problem


Hi,

I'm using Jakarta Commons Net's FTPClient to do FTP transfers.  I use version 
1.4.1 on J2SDK 1.4.2_11.

I'm trying to abort an FTP transfer in a separate thread.

What happens is:
1- The thread that is downloading the file is not interrupted so the file is 
all downloaded
2- Since the download thread is not interrupted, the responses are not handled 
properly:
   * The thread that is calling abort() gets a 426 - transfer aborted response
   * The thread that is downloading the file get 226 ABOR command succesful

Following this message is a sample program to reproduce the problem and a 
sample of this program's output...

Is there something that I'm doing wrong?

What would be required to solve the problem?

Thanks a lot for your help!


Ghis


---------- Sample code -------------

import java.io.FileOutputStream;
import org.apache.commons.net.ProtocolCommandEvent;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTPClient;

public class TestsNetCommons
{
    public static void main(String[] pasArgs)
    {
        final Object            oMonitor    = new Object();
        FTPClient               oFtp        = null;
        Thread                  oThread;
        ProtocolCommandListener oListener   = new ProtocolCommandListener()
        {
            public void protocolCommandSent(ProtocolCommandEvent poEvent)
            {
                String sMessage;

                sMessage = poEvent.getMessage();

                if(sMessage != null)
                {
                    sMessage = sMessage.trim();
                }

                // Remove the password from the log files...
                if(sMessage.startsWith("PASS "))
                {
                    sMessage = sMessage.substring(0, 5) + "*****";
                }

                System.out.println("Client:  " + sMessage);
            }


            public void protocolReplyReceived(ProtocolCommandEvent poEvent)
            {
                String sMessage;

                sMessage = poEvent.getMessage();

                if(sMessage != null)
                {
                    sMessage = sMessage.trim();
                }

                System.out.println("Server:  " + sMessage);
            }
        };

        try
        {
            oFtp = new FTPClient();

            oFtp.addProtocolCommandListener(oListener);

            oFtp.connect("127.0.0.1");

            if(oFtp.login("ftptest", "ftptest"))
            {
                final FTPClient oFtpClient = oFtp;

                // Thread used to download a file...
                oThread = new Thread()
                {
                    public void run()
                    {
                        FileOutputStream oOut = null;

                        try
                        {
                            oOut = new FileOutputStream("C:\\bigfile.zip");

                            oFtpClient.retrieveFile("bigfile.zip", oOut);
                        }
                        catch(Exception ex)
                        {
                            ex.printStackTrace();
                        }
                        finally
                        {
                            if(oOut != null)
                            {
                                try
                                {
                                    oOut.close();
                                }
                                catch(Exception ex)
                                {
                                    // Don't care...
                                }
                            }
                        }
                    } // run                };

                oThread.start();

                // Wait a little, then abort the transfer...
                Thread.currentThread().sleep(1000);
                oFtp.abort();

                // Wait for the download thread to finish it's job
                oThread.join();
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(oFtp != null)
            {
                try
                {
                    oFtp.logout();
                    oFtp.disconnect();
                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        }
    }
}


------------- Sample output --------------------

Server:  220 localhost Microsoft FTP Service (Version 5.0).
Client:  USER ftptest
Server:  331 Password required for ftptest.
Client:  PASS *****
Server:  230 User ftptest logged in.
Client:  PORT 127,0,0,1,10,174
Server:  200 PORT command successful.
Client:  RETR bigfile.zip
Server:  150 Opening ASCII mode data connection for bigfile.zip(29716750 bytes).
Client:  ABOR
Server:  426 Connection closed; transfer aborted.
Server:  226 ABOR command successful.
Client:  QUIT
Server:  221


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to