This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
We have written a BTB tool to transfer files from a client to a server application over FTP. The server application is written in Java and we used the JFTPD code as a baseline. In unittesting on a Windows box the code works perfectly. When we moved the server application to pilot on a unix box (Solaris) the application fails. The client can successfully connect over the control port on a non-standard port (not 21). When the client tries to execute a put it fails with the following error on the server application: Connection Refused. It is occuring on the following line of code: Socket dataSocket = new Socket(dataHost, dataPort) where dataHost is a String parameter and dataPort is an Int. The dataPort is being set as the control port + 1.
The JFTPD code that we used as our starting point has a stubbed out method to handle the PASV command, however there is no code to do anything with the command. We seem to think that PASV will resolve our issue of the data port connection being refused.
Are we on the right or are there any other suggestions?
PASV will absolutely fix the problem if the root cause of the problem is a firewall of some kind which is not letting the data connection through. This is a pretty common issue with FTP so it's quite likely to be the case.
This is a little complicated. PASV is not a property of a socket. It's an FTP command, and what it does it change the responsibilities of the client and server with respect to initiating that second connection, the data connection. In "active" mode, the client opens a connection for listening and tells the server "connect to this port, and send the data." Firewalls will block that incoming connection; that's why active mode doesn't work for you.
In passive mode, however, it's up to the server to say "here's a port, connect to this and I'll send the data though the connection." The client firewall will generally be fine with that.
You'll need to look at the RFC here if you're going to implement the PASV command. It really shouldn't be too hard.