SDSU CS 596: Client-Server Programming
Spring Semester, 1997
Doc 10, Concurrent Java Server with Hinges

To Lecture Notes Index
San Diego State University -- This page last updated Feb 25, 1997
----------

Contents of Doc 10, Concurrent Java Server with Hinges

Concurrent Java Server slide # 2
...Issues slide # 5
A New Hinge slide # 8
Principle of Reusable Object Oriented Design slide # 13
Protection from Sloppy ServerEngines slide # 14
A Java Hinge - forName() slide # 17
...JavaServer slide # 19
...Using JavaServer slide # 22

Doc 10, Concurrent Java Server with Hinges Slide # 1
References

Design Patterns, Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1995

The Java Programming Language, Arnold and Gosling, Addison-Wesley, 1996


Doc 10, Concurrent Java Server with Hinges Slide # 2

Concurrent Java Server

First Example

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

class DateServer implements Runnable
     {
     DataInputStream     input;
     PrintStream     output;
     
     public DateServer( InputStream in, OutputStream out )
          {
          input = new DataInputStream( in );
          output = new PrintStream( out );
          }
     
     public void run()  
          {
          try
               {
               String inputLine = input.readLine().toLowerCase();
               if ( inputLine.startsWith("date") )
                    {
                    Date now = new Date();
                    output.println(now.toString());
                    }
               input.close();
               output.close();  
               }
          catch ( IOException howToHandleThis )
               {// A topic to be covered later}
          }     
     }

Doc 10, Concurrent Java Server with Hinges Slide # 3
Network Server Code
class SimpleConcurrentServer
     {
     ServerSocket acceptor;
     
     public SimpleConcurrentServer()  throws IOException
          {
          this( 0 );
          System.out.println("On port " + acceptor.getLocalPort());
          }

     public SimpleConcurrentServer( int portNumber) 
                                        throws IOException
          { acceptor = new ServerSocket( portNumber ); }

     public void run()  throws IOException
          {
          while (true)
               {
               Socket client = acceptor.accept();
               processClientRequest( client );
               }
          }

     private void processClientRequest( Socket client )
                                             throws IOException
          {
          DateServer  handler
          handler = new DateServer( client.getInputStream(),
                                         client.getOutputStream());
          Thread serverThread = new Thread( handler );
          serverThread.setPriority( 4 );
          serverThread.start();
          }
     }

Doc 10, Concurrent Java Server with Hinges Slide # 4
Running the Server

class Test
     {
     public  static  void  main( String  args[] ) throws IOException
          {
          SimpleConcurrentServer test
          test = new SimpleConcurrentServer();
          test.run();
          }
     }


Doc 10, Concurrent Java Server with Hinges Slide # 5

Issues


What to do with all those exceptions?

What priority to run different parts of the server?

How to use the server code to write more servers?

What if DateServer does not close streams?

What if to many clients connect to server?


Doc 10, Concurrent Java Server with Hinges Slide # 6
Extending Server Code
Using Inheritance

class AirlineConcurrentServer extends SimpleConcurrentServer
     {
     public AirlineConcurrentServer() throws IOException
          { super(); }

     public SimpleConcurrentServer( int portNumber) 
                                        throws IOException
          { super( portNumber ); }

     private void processClientRequest( Socket client )
                                             throws IOException
          {
          AirlineServer  handler
          handler = new AirlineServer( client.getInputStream(),
                                         client.getOutputStream());
          Thread serverThread = new Thread( handler );
          serverThread.setPriority( 4 );
          serverThread.start();
          }
     }
class AirlineServer
     {
     //blah
     }


Doc 10, Concurrent Java Server with Hinges Slide # 7
Extending Server Code
Using Inheritance
Outcome


Doc 10, Concurrent Java Server with Hinges Slide # 8

A New Hinge


Use an Interface

interface ServerEngine extends Runnable
     {
     public ServerEngine newInstance( InputStream in, 
                                        OutputStream out );
     }

class DateServer implements ServerEngine 
     {
     DataInputStream     input;
     PrintStream     output;
     
     public ServerEngine newInstance( InputStream in, 
                                        OutputStream out )
          {
          return new DateServer( in, out );
          }
          
     public DateServer() {}
          
     public DateServer( InputStream in, OutputStream out )
          {
          input = new DataInputStream(in);
          output = new PrintStream(out);
          }


Doc 10, Concurrent Java Server with Hinges Slide # 9
DateServer Continued

     public void run()
          {
          try
               {
               String inputLine = input.readLine().toLowerCase();
               if ( inputLine.startsWith("date") )
                    {
                    Date now = new Date();
                    output.println(now.toString());
                    }
               input.close();
               output.close();
               }
          catch ( IOException howToHandleThis )
               {
               // A topic to be covered later
               }
          }     
     }


Doc 10, Concurrent Java Server with Hinges Slide # 10
HingedConcurrentServer

class HingedConcurrentServer
     {
     ServerSocket acceptor;
     ServerEngine engineFactory;
     
     public HingedConcurrentServer( ServerEngine factory)  
                                             throws IOException
          {
          this( 0, factory );
          System.out.println("On port " + acceptor.getLocalPort());
          }

     public HingedConcurrentServer( int portNumber, 
                    ServerEngine factory ) throws IOException
          {
          acceptor = new ServerSocket( portNumber );
          engineFactory = factory;
          }

     public void run()  throws IOException
          {
          while (true)
               {
               Socket client = acceptor.accept();
               processClientRequest( client );
               }
          }


Doc 10, Concurrent Java Server with Hinges Slide # 11
HingedConcurrentServer Continued

     private  void processClientRequest( Socket client )
               throws IOException
          {
          InputStream in = client.getInputStream();
          OutputStream out = client.getOutputStream();

          ServerEngine handler
          handler = engineFactory.newInstance( in , out );

          Thread serverThread = new Thread( handler );
          serverThread.setPriority( 4 );
          serverThread.start();
          }
     }


Doc 10, Concurrent Java Server with Hinges Slide # 12
Using the HingedConcurrentServer

class Test
     {
     public  static  void  main( String  args[] ) throws IOException
          {
          ServerEngine aFactory = new DateServer();
          SimpleConcurrentServer test;
          test = new SimpleConcurrentServer( aFactory );
          test.run();
          }
     }

Other Servers

class Test
     {
     public  static  void  main( String  args[] ) throws IOException
          {
          ServerEngine aFactory = new AirlineServer();
          SimpleConcurrentServer test;
          test = new SimpleConcurrentServer( aFactory );
          test.run();
          }
     }


Doc 10, Concurrent Java Server with Hinges Slide # 13

Principle of Reusable Object-Oriented Design


Program to an interface, not an implementation

Note in Java or C++ we could have used an abstract class to create the

ServerEngine
interface

Benefits of programming to an interface

class ServerThread extends Thread
     {
     ServerEngine handlerFactory;
     Socket client;
     
     public ServerThread( ServerEngine handlerFactory, Socket client)
          {
          this.handlerFactory = handlerFactory;
          this.client = client;
          }
          
     public void run()
          {
          try
               {
               InputStream in = client.getInputStream();
               OutputStream out = client.getOutputStream();

               Runnable clientHandler;
               clientHandler = handlerFactory.newInstance( in, out); 
               clientHandler.run();

               in.close();
               out.close();
               client.close();
               }
          catch ( Exception howToHandleThis )
               {// A topic to be covered later }
          }

     }


Doc 10, Concurrent Java Server with Hinges Slide # 15
Using ServerThread

class SaferConcurrentServer
     {
     ServerSocket acceptor;
     ServerEngine engineFactory;
     
     public SaferConcurrentServer( ServerEngine factory)  
                                             throws IOException
          {
          this( 0, factory );
          System.out.println("On port " + acceptor.getLocalPort());
          }

     public SaferConcurrentServer( int portNumber, 
                         ServerEngine factory ) throws IOException
          {
          acceptor = new ServerSocket( portNumber );
          engineFactory = factory;
          }

     public void run()  throws IOException
          {
          while (true)
               {
               Socket client = acceptor.accept();

               Thread serverThread;
               serverThread = new ServerThread(engineFactory, client);

               serverThread.setPriority( 4 );
               serverThread.start();
               }
          }
     }
Doc 10, Concurrent Java Server with Hinges Slide # 16
Test Program

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

class Test
     {
     public  static  void  main( String  args[] ) throws IOException
          {
          ServerEngine aFactory = new DateServer();
          SaferConcurrentServer  test;
          test = new SaferConcurrentServer( aFactory );
          test.run();
          }
     }



Doc 10, Concurrent Java Server with Hinges Slide # 17

A Java Hinge - forName()


class Example
     {
     public String toString()
          {
          return "This is a simple class";
          }
     }

class Test
     {
     public  static  void  main( String  args[] ) throws Exception
          {
          Class which = Class.forName( "Example" );
          Object whichOne = which.newInstance();
          System.out.println( whichOne.toString() );
          }
     }

Output
This is a simple class


Doc 10, Concurrent Java Server with Hinges Slide # 18
The Magic Methods in Class

public static Class forName(String className) 
                         throws ClassNotFoundException

Returns the runtime Class descriptor for the specified Class.
Parameters:
className - the fully qualified name of the desired Class
Throws: ClassNotFoundException
If the Class could not be found.
public Object newInstance() throws InstantiationException, IllegalAccessException
Creates a new instance of this Class.
Returns:
the new instance of this Class.
Throws: InstantiationException
If you try to instantiate an abstract class or an interface, or if the instantiation fails for some other reason.
Throws: IllegalAccessException
If the class or initializer is not accessible.

Doc 10, Concurrent Java Server with Hinges Slide # 19

JavaServer


class JavaServer
     {
     ServerSocket acceptor;
     ServerEngine engineFactory;
     
     public static void main( String[] arguments ) throws Exception
          {
          LabeledData parameters = new LabeledData();
          parameters.fromCommandLine( arguments );
          
          String serverClass = parameters.getData( "Server" );
          ServerEngine factory = createFactory( serverClass);  
          
          Integer port =  new Integer(      parameters.getData( "Port", "0") );
          JavaServer aServer = new JavaServer( port.intValue(), factory );
          
          if (  parameters.containsKey( "Local" ) )
               {
               aServer.runLocal( );
               return;
               }
               
          if ( ! parameters.containsKey( "Port" ) )     
               System.out.println( "Using port " +  aServer.getPort() );

          if ( parameters.containsKey( "Iterative" ) )
               aServer.runIterative();
          else
               aServer.runConcurrent();
          }


Doc 10, Concurrent Java Server with Hinges Slide # 20
JavaServer Continued

     private static ServerEngine createFactory( String factoryClass )
                                                                  throws Exception
          {
          Class aFactoryClass = Class.forName( factoryClass );
          return (ServerEngine) aFactoryClass.newInstance();
          }
          
     
     public JavaServer( ServerEngine factory)  throws IOException
          {
          this( 0, factory );
          }

     public JavaServer( int portNumber, ServerEngine factory ) 
                                                                 throws IOException
          {
          acceptor = new ServerSocket( portNumber );
          engineFactory = factory;
          }

     public int getPort()
          {
          return acceptor.getLocalPort();
          }
          
     public void runLocal(  )
          {
          ServerEngine engine = engineFactory.newInstance( System.in,
                                                                            System.out );
          engine.run();
          }

Doc 10, Concurrent Java Server with Hinges Slide # 21
JavaServer Continued

     public void runConcurrent()  throws IOException
          {
          while (true)
               {
               Socket client = acceptor.accept();
               Thread serverThread = new ServerThread( engineFactory,
                                                                            client );
               serverThread.setPriority( 4 );
               serverThread.start();
               }
          }

     public void runIterative()  throws IOException
          {
          while (true)
               {
               Socket client = acceptor.accept();
               Thread serverThread = new ServerThread( engineFactory,
                                                                                 client );
               serverThread.run();
               }
          }
     } //JavaServer


Doc 10, Concurrent Java Server with Hinges Slide # 22

Using JavaServer


java JaverServer -Server DateServer

Runs a concurrent DateServer on random port

java JaverServer -Server DateServer -Port 8888

Runs a concurrent DateServer on port 8888

java JaverServer -Server DateServer -Iterative

Runs an iterative DateServer on random port
java JaverServer -Server DateServer -Local

Runs an DateServer locally with I/O connected to standard in and standard out

Adding New Servers

1) Write a new class, say FooBarServer, that implements ServerEngine

2) Compile FooBarServer

3) Run JavaServer

java JaverServer -Server FooBarServer -Local

Doc 10, Concurrent Java Server with Hinges Slide # 23
JavaServer - The Picture


Concurrent JavaServer


----------