Maths Server Using Socket Programming

It is time to implement a more comprehensive network application by using the socket programming APIs you have learned so far. A sample math client-server interaction demonstrating online math server that can perform basic math operations,

package com.techa2zsolution.intf.math;

public interface MathService {
    public double add(double firstValue, double secondValue);
    public double sub(double firstValue, double secondValue);
    public double div(double firstValue, double secondValue);
    public double mul(double firstValue, double secondValue);
}


The implementation of this interface is not related to any network operation. The following code shows a very simple implementation of this interface:

public class PlainMathService implements MathService {
    public double add(double firstValue, double secondValue) {
        return firstValue+secondValue;
    }
    public double sub(double firstValue, double secondValue) {
        return firstValue-secondValue;
    }
    public double div(double firstValue, double secondValue) {
        if(secondValue!=0)
            return firstValue/secondValue;
        return Double.MAX_VALUE;
    }
    public double mul(double firstValue, double secondValue) {
        return firstValue*secondValue;
    }   
}
 Now Implementing Maths Server,

public class MathServer {
    protected MathService mathService;
    protected Socket socket;

    public void setMathService(MathService mathService) {
        this.mathService = mathService;
    }
    public void setSocket(Socket socket) {
        this.socket = socket;
    }
    public void execute() {
        try {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            // read the message from client and parse the execution
            String line = reader.readLine();
            double result = parseExecution(line);
            // write the result back to the client
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream()));
            writer.write(""+result);
            writer.newLine();
            writer.flush();
            // close the stream
            reader.close();
            writer.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    // the predefined protocol for the math operation is
    // operator:first value:second value
    protected double parseExecution(String line)
            throws IllegalArgumentException {
        double result = Double.MAX_VALUE;
        String [] elements = line.split(":");
        if (elements.length != 3)
            throw new IllegalArgumentException("parsing error!");
        double firstValue = 0;
        double secondValue = 0;
        try {
            firstValue = Double.parseDouble(elements[1]);
            secondValue = Double.parseDouble(elements[2]);
        }
        catch(Exception e) {
            throw new IllegalArgumentException("Invalid arguments!");
        }
        switch (elements[0].charAt(0)) {
        case '+':
            result = mathService.add(firstValue, secondValue);
        break;
        case '-':
            result = mathService.sub(firstValue, secondValue);
            break;
        case '*':
            result = mathService.mul(firstValue, secondValue);
            break;
        case '/':
            result = mathService.div(firstValue, secondValue);
            break;
        default:
            throw new IllegalArgumentException("Invalid math operation!");
        }
        return result;
    }
    public static void main(String [] args)throws Exception{
        int port = 10000;
        if (args.length == 1) {
            try {
                port = Integer.parseInt(args[0]);
            }
            catch(Exception e){
            }
        }
        System.out.println("Math Server is running...");
        // create a server socket and wait for client’s connection
        ServerSocket serverSocket = new ServerSocket(port);
        Socket socket = serverSocket.accept();
        // run a math server that talks to the client
        MathServer mathServer = new MathServer();
        mathServer.setMathService(new PlainMathService());
        mathServer.setSocket(socket);
        mathServer.execute();
        System.out.println("Math Server is closed...");
    }
}
 A test client program that can access the math server is shown below:

public class MathClient {
    public static void main(String [] args){
        String hostname = "localhost";
        int port = 10000;
        if (args.length != 2) {
            System.out.println("Use the default setting...");
        }
        else {
            hostname = args[0];
            port = Integer.parseInt(args[1]);
        }
        try {
            // create a socket
            Socket socket = new Socket(hostname, port);
            // perform a simple math operation “12+21”
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream()));
            writer.write("-:12:21");
            writer.newLine();
            writer.flush();
            // get the result from the server
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            System.out.println(reader.readLine());
            reader.close();
            writer.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}