Example: TCP Echo Server

Now that we have looked at the basic network theory, let's try creating our first server app using the TCP protocol. The aim for this app is to allow a single connection from another app and then send back any strings that are sent to it. First we will look at the complete code listing and output, and then we will go into detail as to how the code works.

Code Listing 17-1: TCP echo server
import java.net.*;
import java.io.*;
public class TCPEchoServer
{
 public static void main(String args[])
 {
 int port = 8000;
 ServerSocket serverSocket = null;
 DataInputStream dataInputStream = null;
 DataOutputStream dataOutputStream = null;
 try
 {
 // open a server socket
 serverSocket = new ServerSocket(port);
 System.out.println("Server created on port "+port);
 System.out.println("Awaiting client connection...");
 // await for a client connection
 Socket clientSocket = serverSocket.accept();
 System.out.println("Client connected from
 "+clientSocket.getInetAddress());
 dataInputStream = new DataInputStream
 (clientSocket.getInputStream());
 dataOutputStream = new DataOutputStream
 (clientSocket.getOutputStream());
 }
 catch(IOException e)
 {
 System.out.println("Problems initializing server: "+e);
 System.exit(1);
 }
 // communicate with the client
 try
 {
 dataOutputStream.writeUTF("Welcome to the TCP Echo
 Server!");
 String input;
 while(true)
 {
 // read data in from client
 input = dataInputStream.readUTF();
 System.out.println("You typed: "+input);
 // write data back to client
 dataOutputStream.writeUTF(input);
 }
 }
 catch(IOException e)
 {
 System.out.println("Client disconnected from server");
 }
 try
 {
 serverSocket.close();
 }
 catch(Exception e) { }
 } }


Java End example

When we run the console app, it will sit and wait for a connection from a client. This looks like the following:

Java Click To expand
Screenshot-2: The TCP echo server

Let's now look at the code and see how this works. First we import the java.net.* package, which contains all of the network-related code. We also import the java.io.* package, which we need for the streams. This can be seen in the following two lines of code:

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


Now we define the default port number as 8000 in a variable called port and also create three variables, which we will use to store our ServerSocket, as well as DataInputStream and DataOutputStream, which we will obtain from the connecting client. This can be seen here:

ServerSocket serverSocket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;


Next, we need to actually set up the server on the port that we have defined. To do this, enter a try/catch block and create a ServerSocket object, which creates a stream socket. To create the ServerSocket object, pass the port number into the constructor as follows:

ServerSocket serverSocket = new ServerSocket(port);


Now that we have our server socket, we need to get it to accept a connection from an incoming client. This is done by calling the accept method, which blocks (waits) until a client connects to the server, hence the code does not pass this point until a client connects to the server. When a client does connect, the connecting socket is then returned by our ServerSocket object, and we store it in a Socket object called clientSocket. This can be seen in the following line of code:

Socket clientSocket = serverSocket.accept();


Once a client has established a connection with our server, we then need to set up streams to handle the incoming and outgoing data. To do this, we call the getInputStream and getOutputStream methods of the Socket class to obtain the streams associated with our clientSocket object. We then pass these streams into the constructor for DataInputStream and DataOutputStream objects, respectively. This can be seen in the following two lines of code:

dataInputStream = new DataInputStream(clientSocket.getInputStream());
dataOutputStream = new DataOutputStream
 (clientSocket.getOutputStream());


Note that we also need to catch a possible IOException, which will tell us if the setup of the server has failed. Note that a possible cause of this failing would be if a server were already running on the port that we specified. Next, we want to send the client a welcome message from our server app so that they know they are connected. To do this, we call the writeUTF method of our dataOutputStream object to which we pass a String object. This can be seen here:

dataOutputStream.writeUTF("Welcome to the TCP Echo Server!");


After this, we then go into a loop that loops indefinitely and calls the readUTF method of the dataInputStream, which blocks (waits) for a string to be received from the client. Each time a string is received, it is printed to the server's console window and is then sent straight back to the client via the writeUTF method of the dataOutputStream object. Note that we also catch a possible IOException that will be thrown when the client terminates the connection to the server, which is the normal way for a client to disconnect. Finally, we need to ensure that the socket is closed after the client disconnects, and we need to catch the possible IOException that could be thrown. This can be seen here:

try
{
 serverSocket.close();
}
catch(Exception e) { }


JaVa
   
Comments