Writing The Server Side Of A Socket
Essay by 24 • October 14, 2010 • 2,228 Words (9 Pages) • 2,338 Views
This section shows you how to write a server and the client that goes with it. The server in the client/server pair serves up Knock Knock jokes. Knock Knock jokes are favored by children and are usually vehicles for bad puns. They go like this:
Server: "Knock knock!"
Client: "Who's there?"
Server: "Dexter."
Client: "Dexter who?"
Server: "Dexter halls with boughs of holly."
Client: "Groan."
The example consists of two independently running Java programs: the client program and the server program. The client program is implemented by a single class, KnockKnockClient, and is very similar to the EchoClient example from the previous section. The server program is implemented by two classes: KnockKnockServer and KnockKnockProtocol, KnockKnockServer contains the main method for the server program and performs the work of listening to the port, establishing connections, and reading from and writing to the socket. KnockKnockProtocol serves up the jokes. It keeps track of the current joke, the current state (sent knock knock, sent clue, and so on), and returns the various text pieces of the joke depending on the current state. This object implements the protocol-the language that the client and server have agreed to use to communicate.
The following section looks in detail at each class in both the client and the server and then shows you how to run them.
The Knock Knock Server
This section walks through the code that implements the Knock Knock server program. Here is the complete source for the KnockKnockServer class.
The server program begins by creating a new ServerSocket object to listen on a specific port (see the statement in bold in the following code segment). When writing a server, choose a port that is not already dedicated to some other service. KnockKnockServer listens on port 4444 because 4 happens to be my favorite number and port 4444 is not being used for anything else in my environment:
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
ServerSocket is a java.net class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket throws an exception if it can't listen on the specified port (for example, the port is already being used). In this case, the KnockKnockServer has no choice but to exit.
If the server successfully connects to its port, then the ServerSocket object is successfully created and the server continues to the next step--accepting a connection from a client (shown in bold):
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
The accept method waits until a client starts up and requests a connection on the host and port of this server (in this example, the server is running on the hypothetical machine taranis on port 4444). When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to a new port. The server can communicate with the client over this new Socket and continue to listen for client connection requests on the ServerSocket bound to the original, predetermined port. This particular version of the program doesn't listen for more client connection requests. However, a modified version of the program is provided in Supporting Multiple Clients.
After the server successfully establishes a connection with a client, it communicates with the client using this code:
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
// initiate conversation with client
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if outputLine.equals("Bye."))
break;
}
This code:
Gets the socket's input and output stream and opens readers and writers on them.
Initiates communication with the client by writing to the socket (shown in bold).
Communicates with the client by reading from and writing to the socket (the while loop).
Step 1 is already familiar. Step 2 is shown in bold and is worth a few comments. The bold statements in the code segment above initiate the conversation with the client. The code creates a KnockKnockProtocol object-the object that keeps track of the current joke, the current state within the joke, and so on.
After the KnockKnockProtocol is created, the code calls KnockKnockProtocol's processInput method to get the first message that the server sends to the client. For this example, the first thing that the server says is "Knock! Knock!" Next, the server writes the information to the PrintWriter connected to the client socket, thereby
...
...