ITTP server

Project : ittpServer

Screen Shot

ITTP Server

I. Server

A. Execution of the Server

1) The Parameters

2) ServerThread and ThreadPool

B. Connections

1) Parser

2) Request

3) Response

4) Protocol

5) IttpException

II. RemoteControl

A. RMI

B. Interface

III. Test

IV. Contribution

GNU

Apache

We designed and implemented a simplified Web server that communicates with clients via TCP connections. This second project allows us to go deeper into the principle of concurrent programming introduced in the first assignment. It illustrates the theory of the network programming.

The first step to realise this server was to establish the communication between a client and a server via a socket. Then we added many clients. Therefore, we have developed the rest of the program (parser for the request, creation of the response) taking care of the different critical sections. This project has underlined trivial problems of synchronisation (Shared variable, critical resources).

In a second time, we developed an interface that allows the modification of the server‘s parameter. This application uses the RMI protocol to communicate.

Server

This server contains the main feature to deliver files through a network. The package ittp contains the server, a client and a control application. The server process listens for incoming TCP connections. Once accepted the server dedicates them their own thread until the request is proceed and the response returned. The control program is a remote application that manages the server. It function is to monitor and to parameter the state of the server in real time. The connection to this control client uses the Remote Method Invocation protocol.

A. Execution of the Server

The server program can be launched with the fallowing options:

- The port listens by the SocketServer.

- The base directory where are store the file that a client may request.

- The path to the error and output log file where are save detailed information.

- Help that prints a synopsis of different options

1)The Parameters

The Parameters class registers the different options send to the program such as:

- the allowed method and headers

- the option : port number and base directory

- the statistic counters: number of request, connection, error and octet transferred

- the threshold for the timeout and number of connection allowed

- the state of the server

2)ServerThread and ThreadPool

Once the parameters set up and the ServerSocket opened, the server runs it own thread ServerThread. This later listens for incoming connection in an endless loop. When a client solicits a file, the server registers the request. If accepted by the ServerSocket, the program starts a new thread and adds it to the thread group ThreadPool.

The ThreadPool and the ServerThread share some variables (the Parameters fields and the standard output and error stream, files). To ensure the mutual exclusion among the threads, public synchronised accessors and mutators provide an access to these shared variables.

We do not know how the standard outputs behave when multiple threads call them at the same time. In consequence, we consider them as potentially critics. The method logInfo registered the different errors and information from the client’s request. The message is written into the stderr or the stdout stream and it is then copied into the log file streams. We also verify that a file requested by a client is locked once open. So that the file cannot be accessed from multiple threads or process unless it has been unlocked.

We try to as much as possible to limit the number share data. To reduce the possibility to share variable, we limited their scope (if possible in private or in local) and to use static only for the constant value.

B.Connections

When the ServerSocket accepts a connection, a new object connect is created. This object is an instance of a private inner class of Server that inherits from the Thread Java Foundation Class. The constructor of this class receives the socket as argument. Once run, the connect Thread checks every 250 ms if the socket input stream is ready. Therefore, a wait() method and a counter define the period corresponding to the timeout. When the connection is proceed, the counter is reset and the connected remain open until a second timeout. If the user asks for a second request, this one will be proceed within the same connection.

int timeout = 10;   // [second]
int frequency = 4; // [hz]
do {
    int counter = 0;
    while (!in.ready () && (!broken)) {
        sleep (1000/frequence);
        if (++ counter > (timeout * frequency))
            broken = true;
    }
    if (!broken) {
        Response response = new Response ();
        RequestParser p = new RequestParser (...);
        Request request = p.parse ();
        request.process (response);
        send (response);
    }
} while (!broken);

1) Parser

The input received from the socket is a text-based stream. We use the class Parser to decode this stream and identify the component. The Parsing with java (Ref. 1) document inspired the design used to build this class. The parser checks only the grammar but not the correctness of the input. This task was delegate to the Request class. The parser stops to read the input when the argument passed does not match the syntax or when it meets two consecutive new lines. If extra data are present after the two new lines, they will be proceeding in a further request. The parser is tolerant to extra space or tabulation character in the request.

2)Request

When the parser identifies a method, it instantiates the request class. This abstract class delegates the implementation of the method process() to its sub-class (Get, Head, Option or Trace). This method is the turning point of the program. In this place, the request is interpreted and the response elaborated.

We choose this architecture to make the program easily extendable. This design was inspired from the textbook Object-Oriented Software Development Using Java (Ref. 1).

If present, the values of the scheme, the port number or the host are compared to the real ones. If they do not match or if the request is older than 10 minutes (Date headers), a 404 File not found error is returned.

The Request class also implements the inner abstract class headers.

The headerlist registers the information about the request headers. The key of this HashMap is a constant string and the value associated is the object’s Headers.

 

This design uniforms the way to access to the headers and masks the machinery of the code. The parser sets up the headers when these ones are encounter. Before to pick up the value, the method (get, trace…) tests if the header isUsed().

The Parser ends its task when the different values are store (and checked) in the request object. If and only if no errors are present, the request can be proceed. Therefore, a new object response is created.

3) Response

The response class wraps the message that is returned to the client. It design is close to the one of the Request. A HashMap registered the list of Headers. This inner class contains two abstract method setUsed() and setAllowed() that are setup when the request is proceed. The inner class Body stores the file that the client may request. The Body also calculates the lengths and the md5 key.

The inner class Code provides a set of methods and constant related to the error (or success) code enclosed within the headers. The two methods toString() and toStream() returned the formatted response ready to be send through the socket. The ByteArrayInputStream and SequenceInputStream JFC have been used to convert the mixed text and byte array to data steam.

4) Protocol

Both Request and Response extends the class Protocol. This class registers the common information such as the version of the protocol and the format of the date.

5)IttpException

When an error occurs in the program, this class is invoked to carry out the message to the Connect class (the class extending the thread JFC that proceeds the socket information). When this exception is catch, the request containing the appropriate response error code is immediately send back to the client and the connection closed.

The constructor of this Class requires two arguments: the detailed message of the error saved on the error log file and the response code. This class extends the RuntimeException class.

I. RemoteControl

The class Parameters that holds the different information related to the server implements the interface RemoteControl. This one extends the Remote interface. The parameters could now be control from a remote client thanks to the RMI protocol.

A. RMI

This protocol allows invoking method from a remote host. In our case, the methods we wish to access are the ones that control the server. To implement this protocol, we use the program rmic.exe that generates the stubs from the server and the control. Once the correct security policy setup, the control client can access to the method on parameters class. This remote object behaves as if it is a local object. The documentation of the java shows a useful tutorial to implement this kind of connection (ref. 2). All the accesses to the interface remoteControl are synchronized: we had to prevent their access from multiple threads at the same time.

B. Interface

The control client uses the Swing JFC to construct the window. This offers a high graphical quality for the component and an easiness to use. The GUI’s structure (Figure XXX) is based on two dialogs.

The main dialog let the user choose what action he wants to do on the server (start/stop, change the timeout, the number of connections, the method or headers allowed).

The statistic dialog offers information about the state of the server (number of request, connection errors, size of the data transferred)

These values are updated in real time (every 100 ms). Therefore, the main panels implement the Runnable interface.

II.Test

Before executing a request, the system does a series of test. Therefore, we have determined several constraints to validate the pre-execution of a command (Table 2.3). If the request is not valid, an ittpException is thrown. If correct, the corresponding method in the Request class is proceeding.

The last important part of this project has been to test and search errors in the program. Therefore, we realised a test classes to verify the correctness of the error and the response from the server to critical error. We have used the Junit application to generate the prototype different classes of test. We have evaluated the different possibility of malfunction that may happen. The results obtained (appendix XXX) has spotted some minor failures (generally nullPointerException). In addition, we have test different parameter when the user executes the program. The unexpected exceptions and errors obtained have been correct and no more known bug remained.

The test program has been enclosed to the program and can be execute by the statement:

java -classpath "man1.jar;Path_to_junit.jar" ittp.test.ParserSuite.

III. Contribution

GNU

The class LongOpt and GetOpt imported in our program belong to the library GNU (available on some Linux distribution e.g. Mandrake 9.2). It is original from c++ library getopt.h. This package process the different options sent by the user. The method getopt () returns them in a friendly way. A switch statement proceeds the different parameters. The command line options to be passed in the traditional Unix manner. That is, proceeded by a '-' character for short option and '--' for the long option.

gnu\getopt\Getopt.java

gnu\getopt\LongOpt.java

Apache

We have imported in this program too, some contribution from the apache projects. Especially, we used two tools they provides in their library to encode and decode a base 64 representation object into a string. This method was used to return the md5 encrypted digest headers. The second package used from this project is a function that copies an inputStreanm into an outputStream.

org\apache\commons\io\CopyUtils.java

org\apache\soap\encoding\soapenc\Base64.java

We copied the licence the sources to use these library in their respective directory enclosed in the ittpServer archive.

Conclusion

We tried to solve a problem of shared file on the network in a simple but efficient way. The designs we choose make the system easy to extend or to reuse. To implement a new header or a new method on the server, a developer need just to insert a class on the corresponding package.

However, this server is a good point to apply theory but it could not be use in practice. The level of security is low. We should authenticate the client (or at less add a signature to the request) and insert a protection to the data (may be encode them).

Another improvement could be to not read the entire file (needed to calculate the digest message) even if we do not need to send it. A possibility of improvement will be to open the file, calculate the MD5’s key from a buffer, and close the file before to answer the request.

Appendix

User manual

The ITTP Server contains several separate programs that have to be executed in different terminals. All the commands that follow are executed in the directory ITTPserver:

In a first time, you have to execute rmiregistry (in bin directory of j2sdk). this allows using the RMI application present in the program.

the server can be executed with this command:

%java -classpath . -Djava.security.policy=home\ ITTPserver \ittp.policy -Djava.rmi.server.codebase=file:///home/ITTPserver/ ittp.Server {options}*

The options that can be used are:

-p or --port

The contains the value used by the server. This option allows modifying the number of the port used by the server to communicate with the client. The default value for the port is 36000.

-b or --base_dir

The contains the directory where the client can request a resource. This option allows modifying the directory where the client can request one resource. The default value for the base directory is user.dir.

-l or --ErrLog

The contains the name of the file where the errors are stored. This option allows modifying the name of the file where errors are stored. The default name for this file is logErr.log.

-i or --InfoLog

The contains the name of the file where different information of the server is stored. This option allows modifying the name of the file where the different information about the server is stored. The default name for this file is logInfo.log.

-h or --help

This option prints a synopsis of standard option previous described.

You can execute more than one option in the same time. In addition, the order of the option in the command has no importance in the execution of the server.

Also if you want, you can use the Control Application to manage the server. In this case You must executed in a third terminal the following command:

%java -classpath . -Djava.security.policy=home\ITTPserver\ittp.policy ittp.Control

A new window appears and you can modify several parameters of the server in real time or obtains some statistical information about the operating server.

Ant Support

If you have the software “ant” (jakarta.apache.org/ant), you can use the file build.xml. You can run ant it with

- one of these target (all is default target):

- ant prepare: create the needed directories

- ant realese: compile the java classes

- ant rmic: buil the stub for the server and the client

- ant jar: create the jar archive

- ant javadoc: create the javadoc

- ant all: create jar and javadoc

- ant clean: clean everything


Download
javadoc
software (jar)

thierno a écrit le   2009/06/23 à 22 h 01
bonjour,
je suis étudiant et je travaille sur un projet pareil en ce moment.
j'aurai besoin de vos conseil si vous le voulez bien.
merci de me contacter par mail.
[Write a comment (1)]

contact - link to this site