JaVa
   

Example: TCP Echo Client

Now that we know how the server works, we can look at how we can create a simple client in Java that will interact with our TCP echo server. Let's first look at the complete client-side code to connect to our server and the expected output, and then we will look at how it all works.

Code Listing 17-2: TCP echo client
import java.net.*;
import java.io.*;
public class TCPEchoClient
{
 public static class TCPEchoReader extends Thread
 {
 public TCPEchoReader(DataInputStream input)
 {
 dataInputStream = input;
 active = true;
 }
 public void run()
 {
 while(active)
 {
 try
 {
 String message = dataInputStream.readUTF();
 System.out.println("Received from server:
 "+message);
 }
 catch(IOException e)
 {
 System.out.println(e);
 active = false;
 }
 }
 }
 public boolean active;
 public DataInputStream dataInputStream;
 }
 public static void main(String[] args)
 {
 String address = "127.0.0.1";
 int port = 8000;
 Socket socket = null;
 DataInputStream dataInputStream = null;
 DataOutputStream dataOutputStream = null;
 BufferedReader keyboardReader = null;
 // Connect to the server...
 try
 {
 socket = new Socket(address, port);
 // Obtain the streams...
 dataInputStream = new DataInputStream
 (socket.getInputStream());
 dataOutputStream = new DataOutputStream
 (socket.getOutputStream());
 keyboardReader = new BufferedReader
 (new InputStreamReader(System.in));
 }
 catch(IOException e)
 {
 System.out.println("Problems initialising: "+e);
 System.exit(1);
 }
 try
 {
 // Start the listening thread...
 TCPEchoReader reader = new TCPEchoReader
 (dataInputStream);
 reader.setDaemon(true);
 reader.start();
 String input;
 while(true)
 {
 // read data in from the keyboard
 input = keyboardReader.readLine();
 // send data to server
 dataOutputStream.writeUTF(input);
 }
 }
 catch(IOException e)
 {
 }
 try
 {
 socket.close();
 }
 catch(IOException e) { }
 }
} 


Java End example

So, if we ensure that we are running our TCP echo server to run this new TCP echo client, we will see that it connects to the server. To see it working, type in a line of text followed by a Return, and the same line of text will be echoed back from the server. The following figure is a screen shot showing this in action:

Java Click To expand
Screenshot-3: The TCP echo client

As you can see, all the data that we send to the server is sent back and output to the console window. Let's look at the client code and see how we interact with our server. First we include the network and I/O package, as we did with the server. Then we declare a nested class called TCPEchoReader, which extends the Thread class. This nested class is used to read in data from the server in a separate thread. To the constructor of the TCPEchoReader, we pass in a DataInputStream object, which will relate to the connected socket and be stored in an instance member called dataInputStream. Then we simply set the Boolean flag active to true, so our thread will execute when started. This can be seen here:

public TCPEchoReader(DataInputStream input)
{
 dataInputStream = input;
 active = true;
}


Next, we have the run method, which overrides the inherited run method of the Thread class. In this method, we create a loop, which will run while the active flag is true. Then, we simply call the readUTF method of the dataInputStream, which will block until a string message is read in from the server. When this occurs, it will store the String object in our variable called message, which we then output to the console window. The entire run method can be seen here:

public void run()
{
 while(active)
 {
 try
 {
 String message = dataInputStream.readUTF();
 System.out.println("Received from server:
 "+message);
 }
 catch(IOException e)
 {
 System.out.println(e);
 active = false;
 }
 }
}


Note also here that we caught a possible IOException, which can be thown. If it is thrown, we terminate the loop by setting the active flag to false.

NoteĀ 

Generally, if any IOException occurs, it means that the socket has been disconnected.

So, let's now look at the entry point of the app, the main method. We use the main method thread as the thread for writing data to the server. It may have been a better technique to create a new class, like the TCPEchoReader class, for writing data to the server; however, we are trying to keep the example as simple as possible. First, we define the address and port of the server that we wish to connect to using the following two variables: address and port.

String address = "127.0.0.1";
int port = 8000;


Then we create four variables to contain references to: a Socket, a DataInputStream, a DataOutputStream, and finally a BufferedReader. This can be seen here:

Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
BufferedReader keyboardReader = null;


Next we create a socket by passing in the address and port of the server to which we wish to connect. The connection is performed when you create the Socket object, which is then stored in our socket variable. Once we have the socket, we can then obtain the DataInputStream and DataOutputStream from it, as we did with the server. Then finally, we create a BufferedReader object to read in input from the keyboard. This entire section can be seen here:

try
{
 socket = new Socket(address, port);
 // Obtain the streams...
 dataInputStream = new DataInputStream(socket.getInputStream());
 dataOutputStream = new DataOutputStream
 (socket.getOutputStream());
 keyboardReader = new BufferedReader
 (new InputStreamReader(System.in));
}
catch(IOException e)
{
 System.out.println("Problems initialising: "+e);
 System.exit(1);
}


Notice again how we catch the possible IOException and exit the program at this stage, as an error at this stage would be fatal (i.e., not being able to establish a connection to the server or not being able to get input from the keyboard). Next we create an instance of the TCPEchoReader, set it as a daemon thread and start it reading for incoming messages. Note that it is a daemon thread, so it will terminate if and when the main thread it is running in terminates. Here is the section of code that does this:

TCPEchoReader reader = new TCPEchoReader(dataInputStream);
reader.setDaemon(true);
reader.start();


Finally, we create a while loop, which loops indefinitely (until the program is closed by the user or an IOException occurs). All we do within the loop is read a line from the keyboard by calling the readLine method of the keyboardReader object that we created, and then we send the string retrieved to the server using the writeUTF method of the dataOutputStream. The TCPEchoReader thread will then handle the message coming back from the server. The input handling can be seen here.

String input;
while(true)
{
 // read data in from the keyboard
 input = keyboardReader.readLine();
 // send data to server
 dataOutputStream.writeUTF(input);
}


JaVa
   
Comments