FTP Client implemetation


                                             1.FTP Client Implementation

Introduction:

                     The FTP (File Transfer Protocol) is commonly used for copying files to and from other computers. These computers may be at the same site or at different sites thousands of miles apart. FTP is a general protocol that works on UNIX systems as well as a variety of other (non-UNIX) systems. A user interface for the standard File Transfer Protocol for ARPANET, FTP acts as an interpreter on the remote machine. The user may type a number of UNIX-like commands under this interpreter to perform desired actions on the remote machine.

                     FTP is built on a client-server architecture and utilizes separate control and data connections between the client and server.[1] FTP users may authenticate themselves using a clear-text sign-in protocol but can connect anonymously if the server is configured to allow it.

DISTRIBUTED SYSTEMS LAB
FTP CLIENT:
                          A client makes a TCP connection to the server's port 21. This connection, called the control connection, remains open for the duration of the session, with a second connection, called the data connection, opened by the server from its port 20 to a client port  as required to transfer file data. The control connection is used for session administration (i.e., commands, identification, passwords) exchanged between the client and server using a telnet-like protocol
FTP SERVER:
                          The server responds on the control connection with three digit status codes in ASCII with an optional text message. The numbers represent the code number and the optional text represent explanations or needed parameters. A file transfer in progress over the data connection can be aborted using an interrupt message sent over the control connection

MODES:
                FTP can be run in active or passive mode, which determine how the data connection is established. In active mode, the client sends the server the IP address and port number on which the client will listen, and the server initiates the TCP connection. In situations where the client is behind a firewall and unable to accept incoming TCP connections, passive mode may be used. In this mode the client sends a PASV command to the server and receives an IP address and port number in return. The client uses these to open the data connection to the server.

While transferring data over the network, four data representations can be used[2]:
Data transfer can be done in any of three modes:
  • Stream mode: Data is sent as a continuous stream, relieving FTP from doing any processing. Rather, all processing is left up to TCP. No End-of-file indicator is needed, unless the data is divided into records.
  • Block mode: FTP breaks the data into several blocks (block header, byte count, and data field) and then passes it on to TCP.
  • Compressed mode: Data is compressed using a single algorithm.

 Implementation steps:

·Configure FTP server at a particular system.
·From FTP Client program connect to FTP Server.
·After successful connection, FTP Server is ready to accept FTP command from the clinet.
·From FTP Client program we can send the command using socket connections, which are executed at       FTP server and results are returned back to FTP Client in terms of codes.
List of FTP commands:

            Below is a list of FTP commands that may be sent to an FTP host, including all commands that are standardized in RFC 959 by the IETF. All commands below are RFC 959 based unless stated otherwise. These commands differ in use between clients. For example, GET is used instead of RETR, but most clients parse this into the proper command. In this, GET is the user command and RETR is the raw command.

Command
Description
ABOR
Abort an active file transfer.
ACCT
Account information.
ADAT
Authentication/Security Data (RFC 2228)
ALLO
Allocate sufficient disk space to receive a file.
APPE
Append.
AUTH
Authentication/Security Mechanism (RFC 2228)
CCC
Clear Command Channel (RFC 2228)
CDUP
Change to Parent Directory.
CONF
Confidentiality Protection Command (RFC 697)
CWD
Change working directory.
DELE
Delete file.
ENC
Privacy Protected Channel (RFC 2228)
EPRT
Specifies an extended address and port to which the server should connect. (RFC 2428)
EPSV
Enter extended passive mode. (RFC 2428)
FEAT
Get the feature list implemented by the server. (RFC 2389)
HELP
Returns usage documentation on a command if specified, else a general help document is returned.
LANG
Language Negotiation (RFC 2640)
LIST
Returns information of a file or directory if specified, else information of the current working directory is returned.
LPRT
Specifies a long address and port to which the server should connect. (RFC 1639)
LPSV
Enter long passive mode. (RFC 1639)
MDTM
Return the last-modified time of a specified file. (RFC 3659)
MIC
Integrity Protected Command (RFC 2228)
MKD
Make directory.
MLSD
Lists the contents of a directory if a directory is named. (RFC 3659)
MLST
Provides data about exactly the object named on its command line, and no others. (RFC 3659)
MODE
Sets the transfer mode (Stream, Block, or Compressed).
NLST
Returns a list of file names in a specified directory.
NOOP
No operation (dummy packet; used mostly on keepalives).
OPTS
Select options for a feature. (RFC 2389)
PASS
Authentication password.
PASV
Enter passive mode.
PBSZ
Protection Buffer Size (RFC 2228)
PORT
Specifies an address and port to which the server should connect.
PWD
Print working directory. Returns the current directory of the host.
QUIT
Disconnect.
REIN
Re initializes the connection.
REST
Restart transfer from the specified point.
RETR
Retrieve (download) a remote file.
RMD
Remove a directory.
RNFR
Rename from.
RNTO
Rename to.
SITE
Sends site specific commands to remote server.
SIZE
Return the size of a file. (RFC 3659)
SMNT
Mount file structure.
STAT
Returns the current status.
STOR
Store (upload) a file.
STOU
Store file uniquely.
STRU
Set file transfer structure.
SYST
Return system type.
TYPE
Sets the transfer mode (ASCII/Binary).
USER
Authentication username.

FTP Client Implementation:

import java.net.*;
import java.io.*;
import java.util.*;

public class ftp{
        static Socket DataSocket;
        static DataInputStream ipstream;
        static PrintStream outstream;

        public static void main(String args[])throws IOException {
          if(connect()){
            while(true){
                    System.out.println("Enter your choice: \n");
                    System.out.println("1. Read a file \n");
                    System.out.println("2. Store a file /n");
                    System.out.println("3. List files \n");
                    System.out.println("4. Change directory \n");
                    System.out.println("5. Change to Parent Directory \n");
                    System.out.println("6. Create Directory \n");
                    System.out.println("7. Print Current Directory \n");
                    System.out.println("8. Logout \n");
                    
                    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
                    int option=Integer.parseInt(br.readLine());
           
                    switch(option){
                      case 1:
                            read();
                            break;
                      case 2:
                            store();
                            break;
                      case 3:
                            list();
                            break;
                      case 4:
                            System.out.println("Enter Directory: \n");
                            String name=br.readLine();
                            outstream.print("CWD "+name+"\r\n");
                            break;
                      case 5:
                            outstream.print("CDUP"+"\r\n");
                            break;
                      case 6:
                            System.out.println("Enter Directory: \n");
                            name=br.readLine();
                            outstream.print("MKD "+name+"\r\n");
                            break;
                      case 7:
                            outstream.print("PWD"+"\r\n");
                            break;
                     case 8:
                           outstream.print("QUIT"+"\r\n");
                           System.exit(1);
                           break;
                     default:
                           System.out.println("Choose a valid option!!!\n");
                           break;
                  }
            }
          }
          else
            connect();
       }
       static boolean connect()
       {
          try  {
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter the FTP host address:");
            String host=br.readLine();

            DataSocket=new Socket(host,21);
            ipstream=new DataInputStream(DataSocket.getInputStream());
            outstream=new PrintStream(DataSocket.getOutputStream());

            String s=ipstream.readLine();
            if(s.startsWith("220"))  {
               System.out.println("Connected to server "+host);
               System.out.println("\n Enter Username:\t");
               String uname=br.readLine();
               outstream.print("USER"+uname+"\r\n");
               s=ipstream.readLine();
               if(s.startsWith("331"))  {
                  System.out.println("\n Enter password:\t");
                  String pass=br.readLine();
                  outstream.print("PASS"+pass+"\r\n");
                  s=ipstream.readLine();
                  if(s.startsWith("230"))  {
                        System.out.println("Login successful!!!HAVE A NICE DAY!!!\n");
                        return true;
                  }
               }
            }
            else  {
               System.out.println("Error connecting to server"+host);
               return false;
            }
      }
      catch(UnknownHostException e)
      {   System.err.println(e);   }
      catch(IOException e)
      {   System.err.println(e);   }
      return false;
   }

   static void store()  {
    try  {
      BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
      System.out.println("Enter Filename:  \n");
      String filename=br.readLine();
      FileInputStream inputStream=new FileInputStream(filename);

      outstream.print("PASV"+"\r\n");
      String s=ipstream.readLine();
     
      String ip=null;
      int port=-1;
      int opening=s.indexOf('(');
      int closing=s.indexOf(')',opening+1);
      if(closing>0)  {
            String dataLink=s.substring(opening+1,closing);
            StringTokenizer tokenizer=new StringTokenizer(dataLink,",");
            ip=tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken();
            port=Integer.parseInt(tokenizer.nextToken());

            outstream.print("STOR"+filename+"\r\n");

            Socket dataSocket=new Socket(ip,port);

            s=ipstream.readLine();
            if(!s.startsWith("150"))  {
               throw new IOException("Simple FTP was not allowed to send the file:"+s);
            }

            BufferedInputStream input=new BufferedInputStream(inputStream);
            BufferedOutputStream output=new BufferedOutputStream(DataSocket.getOutputStream());

            byte[] buffer=new byte[4096];
            int bytesRead=0;
            while((bytesRead=input.read(buffer))!=-1)  {
               output.write(buffer,0,bytesRead);
            }
            output.flush();
            output.close();
            input.close();
       }
    }
    catch(UnknownHostException e)
    {   System.err.println(e);   }
    catch(IOException e)
    {   System.err.println(e);   }
 }

 static void read()  {
   try  {
      BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

      System.out.println("Enter Filename \n");
      String filename=br.readLine();

      outstream.print("PASV"+"\r\n");
      String s=ipstream.readLine();
      System.out.println(s);

      String ip=null;
      int port=-1;
      int opening=s.indexOf('(');
      int closing=s.indexOf(')',opening+1);
      if(closing>0)  {
            String dataLink=s.substring(opening+1,closing);
            StringTokenizer tokenizer=new StringTokenizer(dataLink,",");
            ip=tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken();
            port=Integer.parseInt(tokenizer.nextToken())*256+Integer.parseInt(tokenizer.nextToken());

            outstream.print("RETR"+filename+"\r\n");

            Socket dataSocket=new Socket(ip,port);
            s=ipstream.readLine();
            if(!s.startsWith("150"))  {
               throw new IOException("Simple FTP was not allowed to send the file:"+s);
            }

            BufferedInputStream input=new BufferedInputStream(dataSocket.getInputStream());
            FileOutputStream output=new FileOutputStream("New"+filename);

            byte[] buffer=new byte[4096];
            int bytesRead=0;
            while((bytesRead=input.read(buffer))!=-1)  {
               output.write(buffer,0,bytesRead);
            }
            s=ipstream.readLine();
            System.out.println("Finished!"+s);
            output.close();
            input.close();
      }
   }
    catch(UnknownHostException e)
    {   System.err.println(e);   }
    catch(IOException e)
    {   System.err.println(e);   }
  }

  static void list()  {
  try  {
     outstream.print("PASV"+"\r\n");
     String s=ipstream.readLine();
     System.out.println(s);
     String ip=null;
     int port=-1;
     int opening=s.indexOf('(');
     int closing=s.indexOf(')',opening+1);
      if(closing>0)  {
            String dataLink=s.substring(opening+1,closing);
            StringTokenizer tokenizer=new StringTokenizer(dataLink,",");
            ip=tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken()+"."+tokenizer.nextToken();
            port=Integer.parseInt(tokenizer.nextToken())*256+Integer.parseInt(tokenizer.nextToken());
            outstream.print("LIST"+"\r\n");

            Socket dataSocket=new Socket(ip,port);
            s=ipstream.readLine();
           
            DataInputStream input=new DataInputStream(dataSocket.getInputStream());
            String line;
            while((line=input.readLine())!=null)
                        System.out.println(line);
            input.close();
        }
    }
    catch(UnknownHostException e)
    {   System.err.println(e);   }
    catch(IOException e)
    {   System.err.println(e);   }
  }
}
FTP: OUTPUT
C:\Documents and Settings\ADMIN>e:
E:\>cd 8124
E:\8124>cd ftp
E:\8124\ftp>java ftp
Enter the FTP host address:
127.0.0.1
Connected to Server 127.0.0.1
Enter Username: admin
Enter Password: lab3csed
Login Successful!! HAVE A NICE DAY!!!
Enter your choice:
1.Read a file
2.Store a file
3.List files
4.Change Directory
5.Change to Parent Directory
6.Create Directory
7.Print Current Directory
8.Logout
3
227 Entering Passive Mode (127,0,0,1,4,65).
10-26-10  12:00PM                    3 asd.txt
10-26-10  12:01PM                    0 zxc.txt
Enter your choice:
1.Read a file
2.Store a file
3.List files
4.Change Directory
5.Change to Parent Directory
6.Create Directory
7.Print Current Directory
8.Logout
6
Enter Directory: fgh
"� � r f � - XJ& ection to the server's port 21. This connection, called the control connection, remains open for the duration of the session, with a second connection, called the data connection, opened by the server from its port 20 to a client port  as required to transfer file data. The control connection is used for session administration (i.e., commands, identification, passwords) exchanged between the client and server using a telnet-like protocol

FTP SERVER:
                          The server responds on the control connection with three digit status codes in ASCII with an optional text message. The numbers represent the code number and the optional text represent explanations or needed parameters. A file transfer in progress over the data connection can be aborted using an interrupt message sent over the control connection

MODES:
                FTP can be run in active or passive mode, which determine how the data connection is established. In active mode, the client sends the server the IP address and port number on which the client will listen, and the server initiates the TCP connection. In situations where the client is behind a firewall and unable to accept incoming TCP connections, passive mode may be used. In this mode the client sends a PASV command to the server and receives an IP address and port number in return. The client uses these to open the data connection to the server.

While transferring data over the network, four data representations can be used[2]:
Data transfer can be done in any of three modes:
  • Stream mode: Data is sent as a continuous stream, relieving FTP from doing any processing. Rather, all processing is left up to TCP. No End-of-file indicator is needed, unless the data is divided into records.
  • Block mode: FTP breaks the data into several blocks (block header, byte count, and data field) and then passes it on to TCP.
  • Compressed mode: Data is compressed using a single algorithm.

 Implementation steps:

·Configure FTP server at a particular system.
·From FTP Client program connect to FTP Server.
·After successful connection, FTP Server is ready to accept FTP command from the clinet.
·From FTP Client program we can send the command using socket connections, which are executed at       FTP server and results are returned back to FTP Client in terms of codes.