CA597 Tutorial - Client/Server System using Sockets and Data Streams


Content:
We will implement a client/server system. The client - an applet - reads an integer value from the user. A connection with the server via sockets is established. The data (the integer value) is transferred using data streams. The server reads the integer, increments it, and sends the incremented value back to the applet where it will be displayed. This system might only work on one machine (web browser and server on one machine).

Sockets

Java programs can communicate through designated sockets.
A socket is an abstraction that facilitates communication between a server and a client.
Java treats sockets like IO operations, so receiving or sending data via sockets is like reading from a file or writing to it.

Java supports two forms of sockets

We will attempt to establish a connection between an applet (the client) and a server. The server is supposed to run first, it waits for client requests. The server can decide whether to deny the connection or to accept it and respond to the client's request.

On the server side, we define the following:

	ServerSocket serverSocket = new ServerSocket(8765);
This defines a server socket which runs on port 8765. The server shall listen to (and accept) a connection:
	Socket clientSocket = serverSocket.accept();
The server listens until a client request arrives.
	Socket socket = new Socket("localhost",8765);
As said earlier on, this example is only supposed to work on one machine. So, the client tries to connect to port 8765 on the local machine (localhost). Otherwise you would have to specify the server host (by name or IP address).

Client Sending

Now we can use streams to implement the communication between client and server. The client sends an integer value to the server when user has typed in a value and has clicked the "Send" button. The usual event handling has to be implemented.

The integer value to be send is stored in a variable numb:

	int numb = 0;
	...
	numb = Integer.parseInt(numbField.getText());
A PrintWriter shall be used to send the value to the server. The PrintWriter allows us to use a println-method. This is certainly not the most suitable way of transferring simple integers, but it is useful in extensions of this applet.
	PrintWriter toServer = null;
	...
	toServer = new PrintWriter(socket.getOutputStream(), true);
We only need to ask the socket connection to the server for an OutputStream to generate a PrintWriter. We send the value by
	toServer.println(numb);

Server Receiving

The server used a buffered reader based on the input stream from the socket connection to the client to read incoming data.
	BufferedReader fromClient = new BufferedReader(
       		new InputStreamReader(clientSocket.getInputStream()));
It reads incoming data as a line of character. Since the data represents an integer, we convert it into a proper Integer:
	Integer numb =  new Integer(fromClient.readLine());
This is just a control output:
	System.out.println("received: " + numb.intValue());

Server Sending

Now, an incremented integer value shall be send back to the client. Again, we will use a PrintWriter to send data.
	PrintWriter toClient =
        	new PrintWriter(clientSocket.getOutputStream(), true);
The PrintWriter writes to the output stream of the socket connection to the client using the println method.
	toClient.println(numb.intValue()+1);

Client Receiving

Finally, then client has to read and display the incremented integer value. As with the server, we use a buffered reader.
	BufferedReader fromServer = null;
	...
	fromServer = new BufferedReader(
        	new InputStreamReader(socket.getInputStream()));
	...
	numbStr = fromServer.readLine();
Here, we are not going to convert the input string into an integer. Instead, it shall be directly displayed.
	display.setText(numbStr);

The Java code

Here is the full text of the applet:

//
// Client of a Client/Server pair
// reads an integer value from the user and sends it to the server
// receives an incremented integer from the server
//
// Claus Pahl
//

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class NetApplet extends Applet implements ActionListener {
    TextField numbField;
    Label display;
    Socket socket;

    public void init() {

        try {
            socket = new Socket("localhost",8765);
        } catch (UnknownHostException e) {
            System.out.println("Unknown host");
        } catch (IOException e) {
            System.out.println("IO Exception");
            return;
        }

        numbField = new TextField(6);
        add(numbField);

        Button button = new Button("Send");
        add(button);
	button.addActionListener(this);

	display = new Label("No number");
	add(display);

        validate();
    }

    public void actionPerformed(ActionEvent e)
    {
        int numb = 0;
	String numbStr = null;
	BufferedReader fromServer = null;
	PrintWriter toServer = null;

        String actionCommand = e.getActionCommand();
        if (e.getSource() instanceof Button)
            if (actionCommand.equals("Send"))
            {
       		try 
		{
            		numb = Integer.parseInt(numbField.getText());
        	} 
		catch (NumberFormatException ex) 
		{
            		System.out.println("Number Format Exception");
        	}

		try 
		{
			fromServer = new BufferedReader(
				new InputStreamReader(socket.getInputStream()));
			toServer = 
				new PrintWriter(socket.getOutputStream(), true);
		}
		catch (IOException ex) 
		{
            		System.out.println("IO Exception");
        	}
	
        	toServer.println(numb);

        	try 
		{
            		numbStr = fromServer.readLine();
        	} 
		catch (IOException ex) 
		{
            		System.out.println("Applet receive failed:");
        	}

        	display.setText(numbStr);
           }
    }
}
Here is the server code:
//
// Server of a Client/Server pair
// receives an integer value and increments it
// sends the incremented integer back to the client
// uses sockets and data streams
//
// Claus Pahl

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

public class NetServer {
    public static void main(String[] args) {
	try
	{
		ServerSocket serverSocket = new ServerSocket(8765);
		Socket clientSocket = serverSocket.accept();

		BufferedReader fromClient = new BufferedReader(
                	new InputStreamReader(clientSocket.getInputStream()));
        	PrintWriter toClient = 
			new PrintWriter(clientSocket.getOutputStream(), true);

		while (true) 
		{
			Integer numb =  new Integer(fromClient.readLine());
			System.out.println("received: " + numb.intValue());
			toClient.println(numb.intValue()+1);
		}
	}
	catch(IOException ex)
	{
		System.err.println(ex);
	}

    }
}

How to Extend Your Applet

© Claus Pahl