Sei sulla pagina 1di 5

Design and Implementation of a “Remote File

Server” Using Java RMI

Kang Yuan (990-20-2209)

Abstract:

The purpose of this project is to set up a distributed file transfer system,


implementing the functions of file reading and writing using Java stream. The
system creates a simple “file server” using Java RMI, providing a transparent
communication channel transmitting data from one node to the other. The
objective of building this system is to understand the mechanism of Java RMI,
and to learn to how use Java RMI to build a system.

1. Project Requirement:

The problem to be solved in this project is a representative, but simple,


distributed computing problem. A file of data initially resides at site 0. This
data must be transported to site 1 where it is the input to program f. The data
output by program f must be transported to site 2 where it becomes the input
to program g. The output from program g must be returned to site 0. Each site
must be a distinct networked machine, not just different processes executing
on the same machine. Figure 1 shows the required data flow.

site 2
site 1 program f

site 3
program g

Figure 1: required data flow for the project

2. Problem Description:

To meet the requirement of the project, I designed a simple File Server. First,
a file F1 residing on site 1 will be read from site 2 and the client program on
site will append some content at the end of F1 , then it will be sent to site 3

1
as F2. At site 2, content of the F2 will be processed by a “filter” ( here we
simply pick out the lines that start with “rmi”). After processing , the content
will be sent back to site 1 as file F3.

3. Java RMI Mechanism:

The Java Remote Method Invocation (RMI) system allows an object running
in one Java Virtual Machine (VM) to invoke methods on an object running in
another Java VM, thus providing for remote communication between
programs written in the Java . For a typical RMI application, the client invokes
some methods on the remote object created by the server, passes some
object to the server and gets the result of the function which is the object sent
back by the server. RMI uses the client/server structure, and provides
communication channels between the client and the server.

4. How to use RMI to meet the requirement of the project:

For a typical RMI application , data are sent back and forth between the client
and the server. Therefore for a distributed system of three nodes using RMI,
the data flow may be from node 0 to node 1 to node 2, and then go back to
node 1 and node 0. Figure 3 shows the data flow of this structure. It is not a
data loop shown in Figure 1 as required. Hence it doesn’t fit to solve our
problem using the typical RMI implementation.

submit task submit task


Server0/
Client0 Server1
return result Client1 return result

Figure 3: data flow of the client/server in typical RMI implementation

The nature idea to make data flow in the circular direction as we want is to
use the stream conception in java. In java we have inputstream and
outputstream. To manipulate a local data or file, we simply turn it into a
stream. Once the data’s connected with a stream, we can control data flow as
we want. Now we have a distributed environment. The local operation of
“stream” doesn’t work any more. Since we have the distributed mechanism of
RMI, we can extends JAVA stream class and make them work over the RMI.
Once we have a “remote” stream, then user can transparently use those
stream methods just as they use stream on local machine. The client program
can request a file from server using “remote input stream” and write modified
file to another server using “remote output stream”. Users don’t see the
difference of using the stream conception on local machine between using the
remote streams we defined over the network.

In the “File Server” implementation, RemoteOutputStream and


RemoteInputStream are defined. On node 0, server 1 is running. Client 1,

2
which resides on node 1, calls remote input method on server 1 and get the
required file back to node 1. Then client 1 calls the remote output method of
server 2, which is running on node 2 , and outputs the modified file to node 2.
Then client 2(on node 2) calls remote output method on server 1 and output
the modified file back to server 1. Figure 4 gives the structure of the
implementation for the project using Java RMI.

call remote output method


node 0 and ouput file to server 1 in node 2
(server1) (server 2/
stream
client 2)

call remote input call remote output method


method on server 2 and ouput file
node 1
return file in stream (client 1) content to server 2 in stream

Figure 4: Data flow the project implementation with RMI mechanism

5. Remote File Server Implementation:


I create a file server. This server accepts requests from a remote caller and
returns a RemoteObject that is used by wrapper classes to provide
java.io.InputStream and java.io.OutputStream objects that read or write from the
remote file.

First I define the interface by which my input wrapper class interacts with the
remote file .The RemoteInputHandle class can provide methods that correspond
to those required by the java.io.InputStream abstract class. The interface simply
defines the methods required for an InputStream object. ( Since in my application
, only read() is used, I just define read() in it.)

import java.rmi.*;
import java.io.IOException;

public interface RemoteInputHandle


extends Remote
{
public int read( )
throws IOException, RemoteException;

public int read( byte b[] )


throws IOException, RemoteException;

public int read( byte b[], int off, int len )


throws IOException, RemoteException;
}

Then I define RemoteInputHandleImpl class, which provides the implementation


for the RemoteInputHandle interface . The RemoteFileServerImpl class creates a

3
new input handle implementation when a RemoteInputHandle is requested. The
constructor for the implementation class takes one argument: the InputStream for
which we can provide remote access. This makes the handle more useful
because we can provide remote access to any local object that extends
InputStream. This stream is saved in an instance variable (inStream) after the
UnicastRemoteServer superclass's constructor is called. The superclass
constructor is called because it needs to set things up to listen for requests from
remote clients.

The RemoteInputStream class extends the abstract InputStream class and uses
the RemoteInputHandle interface. The constructor first contacts a
RemoteFileServer to obtain a RemoteInputHandle reference for the path given
and then stores this handle in an instance variable. The InputStream methods
are mapped into the corresponding calls on the RemoteInputHandle (that is, the
RemoteInputStream read() method calls the read() method on the
RemoteInputHandle reference obtained by the constructor).

By this kind of definition I provide a class that can be used any place an
InputStream or OutputStream can be used. For example, now I can create a
PrintStream using a RemoteOutputStream for a log file for an application.
Anything I print to this PrintStream is written to the log file on the remote
machine. Without the wrapper class, I would have to individually extend each
class to use the RemoteInputHandle or RemoteOutputHandle as needed.
The remote interface, implementation, and the wrapper class for the output
stream version are, for the most part, identical to those for input. The methods in
the interface correspond to those for java.io.OutputStream instead of
InputStream, and the RemoteOutputStream object extends OutputStream.

The RemoteFileServer interface provides two methods that the remote input and
output stream classes use to obtain handles :

public interface RemoteFileServer


extends java.rmi.Remote
{

public RemoteOutputHandle getOutStream( String path )


throws java.rmi.RemoteException;

public RemoteInputHandle getInStream( String path )


throws java.rmi.RemoteException;
}

On client side, we will use the RemoteInputStream/RemoteOuputStream to


read/write file from/to a server. The client on two hosts will execute “append” and
“append” functions on file.

4
Server 1 site 0 write to server 1

RemteInputStreamHandle
RemteOnputStreamHandle

remote call

transfer file F1

Client 1(remote stream)


Append lines to file
then output to Server 2 site 1
(Append())

remote call

write to Server 2

Server 2
RemteInputStreamHandle
RemteOnputStreamHandle
Client 2(remote stream) site 2
(filter())

Figure 5: system diagram


System Diagram:

Figure 5 is the system diagram.

Reference:

1.The Java Tutorial - RMI:


http://www.javasoft.com/docs/books/tutorial/rmi/index.html

2. Java Expert Solution by Mark Wutka, et. al .

Potrebbero piacerti anche