Client
Home Up Server Client

 

A Simple Client

There are three classes in this file that implement a client that connects to a server.  The client takes input from the user, sends it to the server, and the server then broadcasts the message to all clients (including the original sender) that it is currently serving.

"EntryPoint" is the name of the main class in the client application.   The main program for this application constructs a new "SimpleClient" and then exits.

To test how the program works, I recommend launching the server and then starting at least two clients so that you can better understand the communication pattern between the server and the clients.

// -------------------------------------
// EntryPoint.java
// Mario Hewardt and John Paxton
// August 22, 1998
// -------------------------------------             
class EntryPoint 
{
	public static void main ( String args[] )
	{
		SimpleClient newClient =new SimpleClient ();
                // force application to exit since thread still running
		System.exit(1);
	}
}        

The heart and soul of the client code is located in the "SimpleClient" class.   The class begins by importing the "net" library to enable "Socket"s to be used and the "io" library to enable streams to be used.

The class declares three variables, a "Socket" to communicate with the server, a "DataInputStream" that enables information that the server sends to the client to be read from a stream, and a "DataOutputStream" that enables the client to send information to the server.

The constructor for the class issues a "connectToServer" command (see below).   If the command is successful (meaning that a server exists on the designated port and a socket could be established),  the "DataInputStream" and "DataOutputStream" are both established.  A "SimpleListenerThread" is then constructed and launched.  The client is given a random identification number between 0 and 99.  The client then sends five messages to the server using the "writeUTF" and "flush" commands.    Remember that the message is not sent from the client to the server until the "flush" command is issued!  Between each message, the client waits for the user to enter input.  The input is obtained via the "System.in.read" command.  The user input is not passed along to the server, it merely allows the user to control when the messages are sent.

The "connectToServer" method establishes a "Socket" between the server and client.  It works by trying to establish a "Socket" on port 45678.  (Ports range from 0 through 2^16.  It is recommended that you use higher numbered ports to avoid conflicts with ports that already might be in use by the operating system.)  If the port can not be established, an "IOException" is raised and an appropriate message is printed.

// --------------------------------------------
// SimpleClient.java
// Mario Hewardt and John Paxton
// August 22, 1998
// --------------------------------------------        
import java.net.*;			// Network functionality
import java.io.*;			// Streams...  
class SimpleClient 
{
	Socket			clientSocket;	
	DataInputStream		clientInput;		
	DataOutputStream	clientOutput;        
	SimpleClient ( )
	{
	  if ( !connectToServer () )
	    System.exit(1);        
	  // We're connected ok..
		        
	  // Set up the Streams that we want to use
	  try {
	    clientInput = new DataInputStream 
             ( new BufferedInputStream (clientSocket.getInputStream()));
	    clientOutput= new DataOutputStream 
            ( new BufferedOutputStream (clientSocket.getOutputStream()));
	  }
	  catch ( Exception e ) { System.exit(1); }
		        
		
	  // Now we start the listener thread
	  SimpleListenerThread listener = new SimpleListenerThread (this);
	  listener.start();        
	  // Client id
	  int clientID = (int) (Math.random () *100);        
	  System.out.println ("ClientID= "+clientID );
	  System.out.println ("--------------");        
	  for ( int x = 0; x < 5; x++ )
	  {
	    System.out.println(x + "--");
	    try {
	      clientOutput.writeUTF (clientID+"#Here's a message");
	      clientOutput.flush();	// IMPORTANT!!!!
	    }
	    catch ( Exception e ) { 
              System.out.println ("Error writing to server"); 
              System.exit(1); 
            }        
	    try {
	      System.in.read();
	    }
	    catch ( Exception e ) { 
              System.out.println ("AHA");
              System.exit(1); 
            }
	  }        
          System.out.println("bye bye");
	}    
	// code that handles the initial connection to the server
	// ------------------------------------------------------
	protected boolean connectToServer ( )
	{
	  try {
	    clientSocket = new Socket ("cs.montana.edu", 45678);
	    return true;
	  }
	  catch ( IOException e ) { 
            System.out.println ("Error connecting to server"); 
            return false; 
          }
	}        
}        

The class "SimpleListenerThread" is spawned by the "SimpleClient" class (see above).  Its purpose is to listen at the socket that connects the server to the client.  Anytime the server sends information, the "SimpleListenerThread" detects it and displays it.

How does the "SimpleListenerThread" work?  The constructor for the class sets "parent" to point to an instance of the "SimpleClient" class that constructs the "SimpleListenerThread" in the first place.  The run method sits in an infinite loop.  The thread issues a "readUTF" to the "DataInputStream" located in its "parent".  The "readUTF" command causes the thread to sleep until there is actually data in the "DataInputStream".  At that point, the message is written to the terminal and the process repeats.

// -------------------------------------------
// SimpleListenerThread.java
// Mario Hewardt and John Paxton
// -------------------------------------------        
class SimpleListenerThread extends Thread
{        
	SimpleClient	parent;        
	SimpleListenerThread ( SimpleClient par )
	{
		parent = par;
	}
        
	// reads from the input...
	public void run ( )
	{
		while ( true )
		{
		  try {
		    System.out.println("in listener thread");
		    String msg = parent.clientInput.readUTF ();	  
		    System.out.println ("Message: "+msg );
		  }
		  catch ( Exception e) { System.exit(1); }
		}
	}
}