Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / September 2006

Tip: Looking for answers? Try searching our database.

jakarta/commons.net

Thread view: 
Christopher Smith - 05 Sep 2006 06:32 GMT
I'm having a devil of a time getting the jakarta ftp lib to work
correctly.

The problem seems to be that the server I want to download to is behind a
firewall. I'm setting the mode to PASV via the command ftp.enterLocalMode
() but it's not working.  Here's a snippet and the resulting output.  
Anyone know of any problems that are specific to Jakarta?

< begin snippet >
// setup the ftp connection
               FTPClient ftp = new FTPClient ();
               ftp.connect (src);
               ftp.login ("xxxx","xxxx");

               ftp.setRemoteVerificationEnabled(false);            
              System.out.println("..remote verify off");
               System.out.println ("FTP:  Connected to " + src +".");
               System.out.print (ftp.getReplyString ());
               ftp.enterLocalPassiveMode();
               System.out.print (ftp.getReplyString ());
               System.out.println (ftp.getStatus ());
               System.out.println(ftp.getPassiveHost());
               System.out.println(ftp.getPassivePort());
                   
               InputStreamReader isr = null;
               try {
                   isr = new InputStreamReader (ftp.retrieveFileStream    
                                ("xxxx.csv"));
                   boolean success = ftp.completePendingCommand();
               } catch (FTPConnectionClosedException e){
                   System.out.print (ftp.getReplyString ());
                   e.printStackTrace();
               } catch (IOException e) {
                   System.out.print (ftp.getReplyString ());
                   e.printStackTrace();
               } catch (Exception e) {
                   System.out.print (ftp.getReplyString ());
                   e.printStackTrace();
               }

< end snippet>

< begin output >
Beginning timestamp Tue Sep 05 01:23:30 EDT 2006
..remote verify off
FTP:  Connected to XXX.XXX.com.
200 Switching to ASCII mode.
200 Switching to ASCII mode.  
211-FTP server status:
    Connected to XXX.XXX.XXX.X
    Logged in as ftpsecure
    TYPE: ASCII
    No session bandwidth limit
    Session timeout in seconds is 300
    Control connection is plain text
    Data connections will be plain text
    At session startup, client count was 1
    vsFTPd 2.0.1 - secure, fast, stable
211 End of status

null     <<< notice that it's not returning the passive host address
-1       <<< or the port!

It ultimately times out.

Any ideas?
Gordon Beaton - 05 Sep 2006 07:19 GMT
> I'm having a devil of a time getting the jakarta ftp lib to work
> correctly.
[quoted text clipped - 4 lines]
> resulting output. Anyone know of any problems that are specific to
> Jakarta?

According to the documentation for getPassiveHost(), you must open the
data connection before the method can return a valid value.

However your timeout is likely due to the fact that your remote server
is behind a firewall, and the firewall has not been configured to
accept incoming connections on ephemeral ports (such as those normally
used for FTP data connections). Try using active mode instead.

If you're unsure, get Ethereal and observe the actual traffic.

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

Christopher Smith - 05 Sep 2006 12:09 GMT
Gordon Beaton <n.o.t@for.email> wrote in news:44fd1706$0$17143$8404b019
@news.wineasy.se:

> According to the documentation for getPassiveHost(), you must open the
> data connection before the method can return a valid value.

Thanks..could you please clarify, what does "open" mean in this case?  I
thought I was doing that if means connecting and logging in to the ftp
server first.
Gordon Beaton - 05 Sep 2006 12:30 GMT
> Thanks..could you please clarify, what does "open" mean in this
> case? I thought I was doing that if means connecting and logging in
> to the ftp server first.

FTP uses a control connection to send commands from client to server
and to receive status and other information from the server. A single
control connection is made from client to server, and it remains open
for the duration of the session.

But files are transferred using a separate data connection for each
transfer.

You have already opened the control connection, but the PASV command
determines how the *data* connection(s) will be made. In PASV mode,
the server opens a second ServerSocket, then responds with its address
and port number for the client to connect to. In active mode, the
client opens a ServerSocket, then sends its address and port number
for the server to connect to.

getPassiveHost()/getPassivePort() are used after establishing a data
connection. In your example, you have attempted to use them after
establishing the control connection, but before establishing any data
connection, so you get null/-1.

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

Christopher Smith - 07 Sep 2006 03:49 GMT
Gordon Beaton <n.o.t@for.email> wrote in news:44fd5fe5$0$17139$8404b019
@news.wineasy.se:

> You have already opened the control connection, but the PASV command
> determines how the *data* connection(s) will be made. In PASV mode,
> the server opens a second ServerSocket, then responds with its address
> and port number for the client to connect to. In active mode, the
> client opens a ServerSocket, then sends its address and port number
> for the server to connect to.

This makes it much clearer...thanks.  So got ethereal, and am looking at
the packets.

Okay, very weird.

It appears that:
1.  the connection goes fine on port 21.
2.  the passive request is issued to the ftp server.
3. the ftp server responds with the correct address and port data I setup
in the config file (vsftpd)...the ports I told it to use ranged from
1200-1203.
4.  Then the client sends a message (SYN FLAG SET) to the server on the
correct port for the passive transfer (i.e., the open connection makes it
through the firewall).  
5.  the server responds with an acknolwedge from the source port opened
by the client (1203).
6.  The request to transfer the file comes from the client on port 21,
the control port.
7.  THEN THE WEIRD PART.  data starts flowing from the server to the
client.  I can actually see the data through the sniffer...it is correct.
8.  The client even responds with acknowledge ment.
9.  Mysteriously, the client then requests to quit.

What's happening? Is this a situaiton where I need to issue the
completePendingCommand() method or something like that?
Gordon Beaton - 07 Sep 2006 07:27 GMT
> What's happening? Is this a situaiton where I need to issue the
> completePendingCommand() method or something like that?

That's great that you got Ethereal to look at the traffic. It really
helps to understand what is actually happening.

Here you get the InputStream and create an InputStreamReader, but
don't actually read from it:

isr = new InputStreamReader (ftp.retrieveFileStream("xxxx.csv"));

Once the data connection is active the server is able to start sending
data, which gets buffered (to a point) at the client until you start
reading it. But then you do this:

boolean success = ftp.completePendingCommand();

...which (I'm not sure here) interrupts the command. What does
"success" contain after this? I'm not convinced this method is
necessary here, but then I've never used this library for ftp.

Two important things here:

1. in most cases, you should read directly from the InputStream
  returned by retrieveFileStream(), without using an
  InputStreamReader. A *possible* exception to this rule is when you
  know the data is text. However even then you should specify the
  correct character encoding when you create the InputStreamReader.

2. you need to actually *read* the data arriving from the server. Read
  until you get EOF (InputStream.read() returns -1), then close the
  InputStream.

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e

Gordon Beaton - 07 Sep 2006 07:34 GMT
> 1. in most cases, you should read directly from the InputStream
>    returned by retrieveFileStream(), without using an
>    InputStreamReader. A *possible* exception to this rule is when you
>    know the data is text. However even then you should specify the
>    correct character encoding when you create the InputStreamReader.

...and if you aren't expecting text, you should always use
setFileType(FTP.IMAGE_FILE_TYPE), otherwise the data may be corrupted
by the transfer.

/gordon

Signature

[ don't email me support questions or followups ]
g o r d o n  +  n e w s  @  b a l d e r 1 3 . s e



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.