Friday, March 27, 2009

Remote Method Invocation (RMI)

Following file are needed to put on Client
Conversion.java
ConversionClient.java
Data.java

On server:
Conversion.java
ConversionImpl.java
ConversionServer.java
Data.java

Conversion.java
public interface Conversion extends java.rmi.Remote
{
public Data conversion1(Data km) throws java.rmi.RemoteException;
public Data conversion2(Data km) throws java.rmi.RemoteException;
}


Data.java
import java.io.*;
public class Data implements Serializable {
    private static final long serialVersionUID = 1L;
    private float km;
    private int miles;
    private long foot;

    public Data() {
    }

    public float getKm() {
        return km;
    }

    public void setKm(float km) {
        this.km = km;
    }

    public int getMiles() {
        return miles;
    }

    public void setMiles(int miles) {
        this.miles =miles ;
    }

    public long getFoot() {
        return foot;
    }

    public void setFoot(long foot) {
        this.foot = foot;
    }
}

ConversionClient.java
import java.rmi.Naming; 
import java.rmi.RemoteException; 
import java.net.MalformedURLException; 
import java.rmi.NotBoundException; 
import java.io.*; 
import java.util.*;
import java.net.*;
public class ConversionClient
{
public static void main(String[] args) throws Exception
{
// Converting the hostname to ip address
InetAddress ia=InetAddress.getByName(args[0]);
// Looking up for the remote object in remote server
Conversion c=(Conversion) Naming.lookup("rmi://"+ia.getHostAddress()+":3000/ConversionServer");
// Enter kilometers
System.out.println("Enter Kilometers\n");
Scanner ob=new Scanner(System.in);
float km=ob.nextFloat();
System.out.println("val is "+km);
Data d=new Data();
d.setKm(km);
//passing values to two methods
int s=c.conversion1(d).getMiles();
long t=c.conversion2(d).getFoot();

// printing out the values 
System.out.println(km+"Kilometers ="+s+"Miles ");
System.out.println(km+"Kilometers ="+t+"Foot ");
}
}

ConversionImpl.java
import java.rmi.Naming; 
import java.rmi.RemoteException; 
import java.net.MalformedURLException; 
import java.rmi.NotBoundException; 

public class ConversionImpl extends java.rmi.server.UnicastRemoteObject implements Conversion
{
private static final long serialVersionUID = 1L;
public ConversionImpl() throws java.rmi.RemoteException
{
super();
}
// converts from Km to Miles
public synchronized Data conversion1(Data value) throws java.rmi.RemoteException
{
int r=(int)Math.round(value.getKm() * 0.62137119);
//System.out.println("r="+r);
value.setMiles(r);
return value;
}
// converts from Km to Foot
public synchronized Data conversion2(Data value) throws java.rmi.RemoteException
{
long r=(long)Math.round(value.getKm() * 3280.8399);
//System.out.println("r="+r);
value.setFoot(r);
return value;
}
}

ConversionServer.java
// This program is used to put the object referrence in rmiregistry
import java.rmi.*;
import java.net.*;
public class ConversionServer
{
public static void main(String args[])throws Exception
{
Conversion c=new ConversionImpl();
InetAddress ia=InetAddress.getLocalHost();
String h=ia.getHostName();
Naming.rebind("rmi://"+ia.getHostAddress()+":3000/ConversionServer",c); // putting the object referrence in rmi registry
}
}

To Compile:

1.a. Copy the folder "client" to the machine where you want to run client.
  b. Go to the folder "client" and run the command
     % javac *.java
2.a. Copy the folder "server" to the machine where you want to run the server.
  b. Go to the folder "server" and run the command
     % javac *.java

To Run the program:

1.On server machine
  a. Open a window to start rmiregistry
     % rmiregistry 3000
  b. Go to the folder "server" 
  c. Start the Server on another window
java ConversionServer 

2.a  Go to the folder "client" in client machine
  b. Start the client using the command
        java ConversionClient

Thursday, March 12, 2009

Friday, March 6, 2009

Remote Procedure Call

RPC (Remote Procedure Call), it is higher level programming to socket programming.

.x files are just like Interface in java. 

conversion.x  
struct conv{  
float x;
};
program conversion{ 
version conversion1_vers{
int conversion1(conv)=1;
}=1;
version conversion2_vers{
int converions2(conv)=1;
}=2;
}= 0x23451111; 

In Conversion.x, conv is a structures used to send a float value.
To generate client and server code use rpcgen
rpcgen -a -C conversion.x

along with client and server, it will also generate makefile.conversion and someother files.



conversion_client.c
/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "conversion.h"
#include
#include /* getenv, exit */


void
conversion_1(float a,char *host)
{
CLIENT *clnt;
int  *result_1;
conv  conversion1_1_arg;

#ifndef DEBUG
clnt = clnt_create(host, conversion, conversion1_vers, "netpath");
if (clnt == (CLIENT *) NULL) {
clnt_pcreateerror(host);
exit(1);
}
#endif /* DEBUG */
conversion1_1_arg.x=a;
result_1 = conversion1_1(&conversion1_1_arg, clnt);
if (result_1 == (int *) NULL) {
clnt_perror(clnt, "call failed");
}
        else
        {
        printf("%.2f Kilometers is equal to %d Miles\n",a,*result_1);
        }
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
}


void
conversion_2(float a,char *host)
{
CLIENT *clnt;
int  *result_1;
conv  converions2_2_arg;

#ifndef DEBUG
clnt = clnt_create(host, conversion, conversion2_vers, "netpath");
if (clnt == (CLIENT *) NULL) {
clnt_pcreateerror(host);
exit(1);
}
#endif /* DEBUG */
converions2_2_arg.x=a;
result_1 = converions2_2(&converions2_2_arg, clnt);
if (result_1 == (int *) NULL) {
clnt_perror(clnt, "call failed");
}
        else
        {
        printf("%.2f Kilometers is equal to %d Feet\n",a,*result_1);
        }
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
}


main(int argc, char *argv[])
{
char *host;
float a;
if (argc <>
printf("usage:  %s server_host\n", argv[0]);
exit(1);
}
host = argv[1];
//According to your logic you need to write your code, here i put "a" as a parameter in both conversion_1 and conversion_2 inorder to send to server.
        printf("Enter kilometers\n");
        scanf("%f",&a);
conversion_1(a,host);
conversion_2(a,host);
}

conversion_server.c
/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "conversion.h"
#include
#include /* getenv, exit */
#include
#include
int *
//After generating this code, we need to write our definition to this methods.
conversion1_1_svc(conv *argp, struct svc_req *rqstp)
{
static int  result;

/*
* insert server code here
*/
        result=(int)floorf((argp->x/1.61)+0.5);
        printf("1st resutl is %d\n",result);
return (&result);
}

int *
converions2_2_svc(conv *argp, struct svc_req *rqstp)
{
static int  result;

/*
* insert server code here
*/
result=(int)floorf(((argp->x) * 3280.839895)+0.5);
        printf("2nd result is %d\n",result);
return (&result);
}

Change the make.conversion to makefile.
mv makefile.conversion makefile

in makefile you need to change the following.
CC=gcc  // default is cc
CFLAGS += -g -DRPC_SVC_FG
RPCGENFLAGS = -C

To compile
$ make

Open two command prompts, one for server and other for client.
$./conversion_server

$./conversion_client