Hi All.

I have been given a task where I have been asked to implement a Java RMI version of an SFTP (Simple File Transfer Protocol) Client / Server. It must use the following commands:

list - list files in current directory
cd - change directory
get filename - copy file from server to client
put - upload file from client to server
bye - close connection

In essence, a FTPServer Factory has to be created which i'm guessing would use the rmi registry to handle requests between the client and server.

I have the RMI part figured out, just trying to get the FTP part working...

I decided to use the Java Library from JScape Inet Factory and all classes compile, the Ftp Server is running and waits for a connection on port 1099 the designated default RMI port.

When the Client starts up it asks user to confirm localhost name and then asks user for username and password, these are hardcoded as "user" and "pass" respectively.

The client then begins to log in, the client finds the RMI name through the registry and then trys to log into the FTP server, but everytime it tries to do this it times out as it cannot see the FTP Server. Any ideas??

I have attached code for FTPServer, the Implementation and the Client...any help would be appreciated

Thanks

RMI FTP SERVER

package server;
import java.net.*;
import java.net.UnknownHostException;
import java.io.*;
import java.util.*;
import java.lang.Thread;
import java.rmi.*;
import java.rmi.Remote;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.*;
import com.jscape.inet.ftp.*;
import com.jscape.inet.ftp.FtpException;
import server.*;
 
 
public class RmiFtpServer {
 
    //static String hostName = "localhost";
    private static String hostName;
    private static int hostPort = 1099;
    static RmiFtpImpl rmi;
 
   public static void main(String[] args) throws RemoteException, FtpException, UnknownHostException {
 
    String host;
    String port;
    String badhost;
    String error;
 
    //System.setSecurityManager(new RMISecurityManager());
 
    try {
 
     InetAddress addr = InetAddress.getLocalHost();
 
     // Get IP Address
     byte[] ipaAddr = addr.getAddress();
 
     // Get Host Name
     String hostName = addr.getHostName();
 
     RmiFtpImpl rmi = new RmiFtpImpl("RmiFtpServer");
     System.out.println("RmiFtpServer object created...");
     System.out.println("Registering FTP Server with RMI Naming service...");
 
     String serverObjectName = "rmi://localhost/RmiFtpServer";
     Naming.rebind(serverObjectName, rmi);
 
     System.out.println("RmiFtpServer bound in RMI registry");
     host = "Bindings Finished. FTP Server hostname is: " + hostName;
     System.out.println(host);
     port = "Waiting for FTP Client requests on port "+ hostPort +" ...";
     System.out.println(port);
   }
    catch (UnknownHostException uhe) {
      badhost = "The host computer name you have specified, "+ hostName +" does not match your real computer name.";
      System.out.println(badhost);
      //System.exit(1);
    }
 
    catch (RemoteException re) {
      error = "Error starting service :"+re;
      System.out.println(error);
      //System.exit(1);
    }
 
    catch (MalformedURLException url) {
        System.out.println("RmiFtpServer URL Error: " + url.getMessage());
    }
 
   }
}

RMI IMPLEMENTATION

[B]package[/B] server;
 
[B]import[/B] java.io.*;[B]import[/B] java.lang.*;
[B]import[/B] java.net.*;
[B]import[/B] java.net.InetAddress.*;
[B]import[/B] java.net.UnknownHostException;
[B]import[/B] java.rmi.server.UnicastRemoteObject;
[B]import[/B] java.rmi.RemoteException;
[B]import[/B] java.util.*;
[B]import[/B] com.jscape.inet.ftp.*;
[B]import[/B] server.*;
 
[B]public[/B] [B]class[/B] RmiFtpImpl [B]extends[/B] UnicastRemoteObject [B]implements[/B] RmiFtp
{ // begin class
 
    [B]private[/B] [B]static[/B] String hostName;
    [B]private[/B] String host, user, password;
    [B]private[/B] String name;
    [B]private[/B] [B]int[/B] port;
    String ftpEx;
    Login log;
 
    [B]public[/B] RmiFtpImpl(String s) [B]throws[/B] RemoteException
    { // begin rmiftpimpl
        [B]super[/B]();
        name = s;
    } // end rmiftpimpl
 
    [B]public[/B] [B]boolean[/B] doLogin() 
      [B]throws[/B] RemoteException, UnknownHostException { // begin do login
 
    System.out.println ("doLogin() method begins here...");
 
    //log = new Login(host, user, password, port);
 
    System.out.println ("validation begins...");
 
    System.out.println ("validation should finish here...");
 
            [B]try[/B] { // begin try
          System.out.println ("Attempt to create FTP object...");
 
      InetAddress addr = InetAddress.getLocalHost();
 
      // Get IP Address
      [B]byte[/B][] ipaAddr = addr.getAddress();
 
      // Get Host Name
      String hostName = addr.getHostName();
 
      host = hostName;
      user = "user";
      password = "pass";
 
      Ftp ftpconn = [B]new[/B] Ftp(host,user,password);
      System.out.println ("FTP object created...");
      System.out.println(ftpconn);
          //ftpconn.addFtpListener(this);
          ftpconn.connect();
      System.out.println("connection created...");
          //String results = ftpconn.getDirListingAsString();
          //System.out.println(results);
          //ftpconn.disconnect();
          [B]return[/B] [B]true[/B];
      } // end try
 
      [B]catch[/B] (FtpException ex) { // begin catch
      ftpEx = "FTP Exception: "  + ex.getMessage();
      System.out.println(ftpEx);
      [B]return[/B] [B]false[/B];
 
      } // end catch
 
      [B]catch[/B] (UnknownHostException uhe) {
      System.out.println("Host Exception Error: " + uhe.getMessage());
      [B]return[/B] [B]false[/B];
    }
      }
}

FTP RMI CLIENT

/*
 
package client;
 
/**
 *
 * @author
 */
[B]import[/B] com.jscape.inet.ftp.*;
[B]import[/B] java.io.*;
[B]import[/B] java.net.*; 
[B]import[/B] java.net.MalformedURLException;
[B]import[/B] java.rmi.*;
[B]import[/B] java.rmi.Remote;
[B]import[/B] java.rmi.Naming;
[B]import[/B] java.rmi.RMISecurityManager;
[B]import[/B] java.util.Enumeration;
[B]import[/B] server.RmiFtp;
 
[B]public[/B] [B]class[/B] RmiFtpClient [B]extends[/B] FtpAdapter [B]implements[/B] FtpListener  {
 
[B]public[/B] [B]static[/B] String servHost;
[B]private[/B] [B]static[/B] String hostName;
 
[B]public[/B] [B]static[/B] [B]void[/B] main(String[] args) [B]throws[/B] RemoteException {
 
    [B]if[/B] (System.getSecurityManager() == [B]null[/B])
    {
    System.setSecurityManager([B]new[/B] RMISecurityManager());
    }
 
    servHost = "localhost";
    [B]if[/B] (args.length < 1) {
        System.out.println("Usage: java RmiFtpClient <rmihost>");
        }
 
    [B]else[/B] {
        servHost = args[0];
    }
 
    [B]new[/B] RmiFtpClient();
}
 
    [B]public[/B] RmiFtpClient() {
 
    String host;
    String user;
    String password;
    //int port = 1099;
 
    RmiFtp rmi = [B]null[/B];
 
        [B]try[/B] {
 
        InetAddress addr = InetAddress.getLocalHost();
 
        // Get IP Address
            //byte[] ipaAddr = addr.getAddress();
 
        // Get Host Name
        String hostName = addr.getHostName();
 
 
        BufferedReader reader = [B]new[/B] BufferedReader([B]new[/B] InputStreamReader(System.in));
            System.out.print("Enter Ftp hostname (e.g. ftp.yourhost.com): " + hostName);
            host = reader.readLine();
            System.out.print("Enter username (e.g. anonymous): ");
            user = reader.readLine();
            System.out.print("Enter password (e.g. password): ");
            password = reader.readLine();
            rmi = (RmiFtp)Naming.lookup("rmi://localhost/RmiFtpServer");
        System.out.println ("Naming OK");
        System.out.println("Logging in to FTP Server...");
            rmi.doLogin();
        System.out.println("did it work?");
            }
 
    [B]catch[/B](RemoteException re) {
            System.out.println("FTP RemoteException Error: " + re.getMessage());
            }
 
    [B]catch[/B](IOException io) {
            System.out.println("FTP IO Error: "  + io.getMessage());
            }
 
        [B]catch[/B](NotBoundException e) {
            e.printStackTrace();
            }
 
    }
}

what do you mean, it "cannot see the server"?

Log the remote object as it is returned, what are you getting for the endpoint?

If your hostsfile is configured wrong your server might pass your clients an incorrect IP address to use when making calls on the remote object, leading to those calls getting lost and the client reporting a "connection refused" or similar error.

I decided to use sockets to run the FTP server and call the methods that the FTP Server and Client using RMI, is this correct?

Well i've been trying to implement this but everytime I try and launch the server I get an IOException error

RmiFtpServer IO Error: Connection refused: connect

if i run the server without calling the Socket outgoing call then it works in a way.

I thought it could have been my firewall refusing the connection, but then if the program is running on 1 machine would the firewall even be used, i didn't think so. So I opened ports 20 and 21 (FTP Ports) but still produced the same exception error.

Any ideas??

RMI SERVER

package server;
[LEFT]import java.net.*;

import java.net.UnknownHostException;
[LEFT]import java.io.*;
import java.util.*;
import java.lang.Thread;
import java.rmi.*;
import java.rmi.Remote;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.*;
import com.jscape.inet.ftp.*;
import server.*; 
public class RmiFtpServer extends Thread {
  //static String hostName = ;
  // The port which FTP server will connect to
  public static final int SERVER_PORT = 21;[/LEFT]
 
[LEFT]  // The data port
  public static final int SERVER_DATA_PORT = 20;[/LEFT]
 
[LEFT]  // The server name
  public static final String SERVER_HOST = "localhost"; [/LEFT]
 
[LEFT]  // The port this server is listening on
  private int portListen;[/LEFT]
 
 
[LEFT] // private static int hostPort = 1099;
  private static RmiFtpImpl rmi;[/LEFT]
 
[LEFT]  private static String hostName;
  private static String r;
  private Socket incoming;
  private Socket outgoing;
  private int counter;
public static void main(String[] args) throws RemoteException, UnknownHostException {
  String host;
  String port;
  String badhost;
  String error;[/LEFT]
 
[LEFT]  //Socket outgoing;
  //BufferedReader in = null;
  //PrintWriter out = null;
  String line;
  int i = 1;
  try {  
  InetAddress addr = InetAddress.getLocalHost();[/LEFT]
 
[LEFT]      // Get IP Address
      byte[] ipAddr = addr.getAddress();[/LEFT]
 
[LEFT]      // Get hostname
      String hostname = addr.getHostName();
System.out.println("begin here...");
   RmiFtpImpl rmi = new RmiFtpImpl("RmiFtpServer");
   System.out.println("RmiFtpServer object created...");
   System.out.println("Registering FTP Server with RMI Naming service...");
   String serverObjectName = "rmi://localhost/RmiFtpServer";
   Naming.rebind(serverObjectName, rmi);
   hostName = SERVER_HOST;
   System.out.println("RmiFtpServer bound in RMI registry");
   host = "Bindings Finished. FTP Server hostname is : " + hostName;
   System.out.println(host);
   ServerSocket s = new ServerSocket(21);[/LEFT]
 
[LEFT]   int portListen = SERVER_PORT;[/LEFT]
 
[LEFT]   port = "Waiting for FTP Client requests on port "+ portListen + " ...";
   System.out.println(port);[/LEFT]
 
[LEFT]   System.out.println("begin socket...");
   Socket outgoing = new Socket(hostName, 20);
   //String request="login\r\n";
   byte[] b = new byte[1024];
  // OutputStream out = outgoing.getOutputStream();
  OutputStream out = outgoing.getOutputStream();
  BufferedInputStream in = new BufferedInputStream(outgoing.getInputStream());
  System.out.println(in.read(b));[/LEFT]
 
 
[LEFT]   //System.out.println("start client data transfer...");
   //String clientData = in.readLine();
   //System.out.println("receive data from client " + clientData);[/LEFT]
 
[LEFT]   //System.out.println("send data to client " + clientData);
   //out.println("This is message from server");
   //out.flush();[/LEFT]
 
[LEFT]   //out.write(request.getBytes());[/LEFT]
 
[LEFT]   //System.out.println(in.read(b));
   //for(;;)
   //{
      Socket incoming = s.accept();
System.out.println(s.getInetAddress());
new RmiFtpServer(incoming,i).start();
i++;
     // }
  }[/LEFT]
 
[LEFT]    catch (UnknownHostException uhe) {
    badhost = "The host computer name you have specified, "+ hostName +" does not match your real computer name.";
    System.out.println(badhost);
    //System.exit(1);
  }[/LEFT]
 
[LEFT]    catch (RemoteException re) {
    error = "Error starting service :"+re;
    System.out.println(error);
    //System.exit(1);
  }[/LEFT]
 
[LEFT]  catch (MalformedURLException url) {
      System.out.println("RmiFtpServer URL Error: " + url.getMessage());
  }
  catch (IOException io) {
      System.out.println("RmiFtpServer IO Error: " + io.getMessage());
 }
 }
    public RmiFtpServer(Socket income, int c)
    {
           System.out.println("Entered Constructor");
           incoming = income;
    counter = c;
           }
  public void run()
  {
int lng, lng1, lng2, i, ip1, ip2, ip = 1, h1;
String a1, a2, di, str1, user="", host, dir;
System.out.println(r);
dir = r;
InetAddress inet;
InetAddress localip;[/LEFT]
 
[LEFT]try {
 inet = incoming.getInetAddress();
 localip = inet.getLocalHost();
 host = inet.toString();
 h1 = host.indexOf("/qc308_serv");
 host = host.substring(h1 + 1);
 System.out.println(host);[/LEFT]
 
[LEFT] BufferedReader in = new BufferedReader (new InputStreamReader(incoming.getInputStream()));
 PrintWriter out = new PrintWriter(incoming.getOutputStream(),true);[/LEFT]
 
[LEFT] out.println("SERVER: 220 FTP Server ready.\r");
}
catch (Exception e) {
System.out.println(e);
}[/LEFT]
 
[LEFT]  }[/LEFT]

[/LEFT]

So, the server can't bind the remote.
Hardly surprising if you have no RMI registry running.

And you never even try to find the registry you're trying to register your remote object with, so it's no surprise you can't register it.

RMI Registry works fine, I created 2 batch files and get output and no RemoteExceptions, I can attach screen shots if necessary

Follow up to previous post. I think I have Sockets issued sorted, I called them before initialising RMI and it seems to have worked.

I have attached a screenshot of the RMI registry and server running, plus the 2 batch files for jwenting's benefit as he said I wasn't running them.

I just need to work out how to run FTP commands using the inetfactory.jar library, i just get connection times out :(

Any ideas why the connection is not starting, i think it's something to do with the FTP not seeing the server running despite it being set up as a ServerSocket on port 21...hmmm

I will post more code later...

Click here for screenshot as mentioned...

Thanks

I know that RMI runs on port 1009, but I need to create an FTP Client Server solution so have decided to use Sockets running on port 21 and the File class, i've scrapped using FTP classes. I will just call the methods which simulate FTP commands using the File class via RMI.

I will get a workaround solution done later.

You can't have it both ways. Either you use RMI and the ports it gives you, or you code your own sockets implementation and use whatever port you want.

This article has been dead for over six months. Start a new discussion instead.