CS102: Client Server Applications

Copyright © 1999, Kenneth J. Goldman


We've seen how TCP/IP works in general to provide communication across the Internet. We've also seen how TCP supports the stream abstraction and how to create and connect to sockets for interprocess communication in Java. In particular, we saw a simple example of how to use the ServerSocket and Socket classes.

Client/Server Paradigm

A very common type of application is one in which a server program runs continuously at a well-known location (address) and other processes, the clients connect to it. This kind of application falls under the client/server paradigm . Client/server application examples include:

Usually, clients communicate only with the server(and not with other clients). However, there are exceptions, but these collaborative kinds of applications usually aren't classified under the client/server paradigm, except for initial setup, perhaps.


Let's develop a simple framework for building a client/server application. In other words, we'll define some general classes that could be used to implement a variety of client/server applications.

What properties do we want from out framework?

  1. to start up a server at a specified port
  2. to specify how to interact with each client
  3. to allow multiple clients to be connected at the same time
  4. to allow clients to be started at any time, as long as the server is running
  5. to specify how the client should interact with the server

We could define two classes, client and server, with the intention that specialized behavior would be defined in subclasses. However, that may prevent the software developer from using some other class to specify the behavior (because multiple inheritance is not allowed). Therefore, we'll define two interfaces:

Now, let's create a Client class that opens a socket to the server, informs the ClientBehavior class of the streams, and starts it running.
Similarly, we want to create a Server class. However, each time we accept a connection, we need to create a new thread to handle it with its own state. So we need a way to produce a new client handler for each request. For this, we'll pass a ClientHandlerFactory to the Server constructor.

Square Server and Client

Check out the SquareSever.java and SquareClient.java for an example of a client and server for the example we did earlier.