6.7 Creating a TCP Server
One of the most enjoyable parts of networking is writing a network server. Clients send requests and respond to data sent back, but the server performs most of the real work. This next example is of a daytime server (which you can test using the client described in Section 6.5).
Code for DaytimeServer
import java.net.*; import java.io.*; // Chapter 6, Listing 2 public class DaytimeServer { public static final int SERVICE_PORT = 13; public static void main(String args[]) { try { // Bind to the service port, to grant clients // access to the TCP daytime service ServerSocket server = new ServerSocket (SERVICE_PORT); System.out.println ("Daytime service started"); // Loop indefinitely, accepting clients for (;;) { // Get the next TCP client Socket nextClient = server.accept(); // Display connection details System.out.println ("Received request from " + nextClient.getInetAddress() + ":" + nextClient.getPort() ); // Don't read, just write the message OutputStream out = nextClient.getOutputStream(); PrintStream pout = new PrintStream (out); // Write the current date out to the user pout.print( new java.util.Date() ); // Flush unsent bytes out.flush(); // Close stream out.close(); // Close the connection nextClient.close(); } } catch (BindException be) { System.err.println ("Service already running on port " + SERVICE_PORT ); } catch (IOException ioe) { System.err.println ("I/O error - " + ioe); } } }
How DaytimeServer Works
For a server, this is about as simple as it gets. The first step in this server is to create a ServerSocket. If this port is already bound, a BindException will be thrown, as no two servers can share the same port. Otherwise, the server socket is created; the next step is to wait for connections.
Since daytime is a very simple protocol and our first example of a TCP server should be a simple one, we use here a single-threaded server. A for loop that loops indefinitely is commonly used in simple TCP servers, or a while loop whose expression always evaluates to true. Inside this loop, the first line you will find is the server.accept() method, which blocks until a client attempts to connect. This method returns a socket that represents the connection to the client. For logging, the IP address and port of the connection is sent to System.out. You'll see this every time someone logs in and gets the time of day.
Daytime is a response-only protocol, so we don't need to worry about reading any input. We obtain an OutputStream and then wrap it in a PrintStream to make it easier to work with. Determining the date and time using the java.util.Date class, we send it over the TCP stream to the client. Finally, we flush all data in the print stream and close the connection by calling close() on the socket.
Running DaytimeServer
Running the server is very simple. The server has no command-line parameters. For this server example to run on UNIX, you will need to modify the SERVICE_PORT variable to a number above 1,024, unless you turn off the default daytime process and run this example as root. On Windows or other operating systems, this will not be a problem. To run the server on the local machine, the following command would be used:
java DaytimeServer