JFtp is a multithreaded, graphical FTP client which I wrote as part of the Internet Programming I course I took at the Royal Institute of Technology (Stockholm, Sweden). JFtp is written in Java. While writing JFtp I had in mind a "nomadic" use, for example on a public computer at a library, where there isn't always a decent FTP client available. This means that JFtp does not read or write any local configuration files.
JFtp's interface mimic that of commonly used FTP clients so it does not take much getting used to on the user's behalf. You are presented with a text input field where you can enter an FTP URL, then either press the [ENTER] key or the Connect button to connect. There are two viewing modes : the file navigator and the log viewer. The user can switch back and forth between them by selecting the appropriate tab.
File navigator mode
In this viewing mode JFtp displays both local and remote files/directories and allows you to upload, download or delete files. You can also adjust the maximum number of FTP control threads and switched between active and passive mode.
The local and remote views are automatically refreshed when they are likely to have changed, for instance upon completion of an upload, download or delete operation.
Log viewer mode
In this view you can have a look at the commands and responses exchanged between the client and the server. Thread startups and exits are also displayed.
Whatever the viewing mode, at the bottom of the screen there is a JTtree which displays the currently running threads and their respective queued tasks. The top node represents the JFtp main thread, its children are JFtpControl control threads and its grandchildren are JFtpData data threads.
All the necessary implementation for visualising the threads and their queues is provided by the JFtpThread class.
Command line arguments
You can optionally pass JFtp command line arguments. To get the list of options you can just run JFtp -h.
[ This is JFtp 0.8.4, a graphical ftp client ] Syntax: JFtp [options] [url] Options: -h - this help message -p - use passive mode [default] -a - use active mode -s - use single control thread [default] -m - use multiple control threads
Remarks on inactive control connections
To avoid getting disconnected by the remote server, JFtp periodically sends a NOOP command on its main control thread (the one used for display). When operating in multiple control connection mode, there can be several control connections open at one time and once they have finished their respective tasks, if they are not re-assigned new tasks an idle timer is started. If after 15 seconds no new operation is queued, the threads logs out and disconnects.
As mentioned above, JFtp is a multithreaded program. JFtp's threads all derive from the JFtpThread class which in turn is derived from the Thread class. The JFtpThread class provides the base for threads with:
- an optional JFtpThread.parent thread.
- a FIFO message JFtpThread.queue
- an array of JFtpThread.children threads
- an optional JTree called JFtpThread.threadTree to display information about the thread, its queue and its children
There are three type of threads in JFtp:
- JFtp is the program's main thread.
- JFtpControl represents an FTP control thread
- JFtpData represents a data connection
The main thread is the heart of the program, it receives input from the user interface and fires up child threads to execute the requested actions. The user is offered two threading models, that is operation with either a single or multiple FTP control connections.
Single thread operation
In single control thread operation, all commands issued by the user are queued to the same control thread. This means that the control thread is no longer available for directory browsing.
Multiple thread operation
In multiple control thread operation, when the processing a file transfer, the main thread goes over the currently established JFtpControl control connections and tries to locate once which is idle (i.e. has no operations in its queue). If it does not find one, it checks whether we have reached the maximum number of threads. If we are allowed to setup and extra thread, a new control connection is established with the remote server and the file transfer can take place. Otherwise, the file transfer operation stays in the queue.
This thread handles an FTP control connection, a TCP connection where commands are exchanged in plain text with the distant server. The state of the connection is tracked so that we can check if a given command is acceptable at a given instant.
The JFtpControl class handles file transfer requests and remote directory listing requests by firing up JFtpData data connections.
This thread handles an FTP data connection. Data connections are initiated for three types of operations:
- retrieving a directory listing (LIST)
- retrieving a distant file (RETR)
- uploading a local file (STOR)
Java's buffered reader and writer are used for the transfer of data to and from the TCP sockets.
Active vs Passive mode
JFtpData can handle connections in either active or passive mode, that is the connection can be initiated either by the server or the client. The corresponding PORT or PASV command is sent upon creation of the connection. In active mode, a ServerSocket is used to wait for the server to connect to a local port.