Block 15 Developing the Calculator application Jin Sa 2018/6/15 Client-server programming
Client-server programming Outline Objectives Problem description Structural design Detailed design Implementation –version 1 Partial GUI implementation –version 2 2018/6/15 Client-server programming
Objectives Help you to do the application part of the assignment Calculator is a simplified version of last year’s assignment The Calculator application is similar to this year’s assignment. This year has an extra aspect – threads sharing the same data, i.e. the counter (not addressed in this unit, see the Thread lecture).
Problem description See handout “CalculatoSimplifed.doc”.
Structural Design – client side
Structural Design – server side Why do we want to have three classes? Rationale?
Detailed Design – Protocol class The state diagram needs revision because …
Implementation – version 1 (no GUI)
Implementation – version 1 (no GUI) Pseudo code Not addressing error detection. (you need to do error detection in your assignment. 2018/6/15 Client-server programming
Version 1 CalcServer- pseudo code public class CalcServer { main(String[] args) { ServerSocket serverSocket; boolean listening = true; serverSocket = new ServerSocket(5555); while (listening) {Socket s= serverSocket.accept(); new CalcThread(s).start();} serverSocket.close(); }
Version 1 CalcThread (1) - pseudo code public class CalcThread extends Thread { private Socket socket; public CalcThread(Socket socket) { super("CalcThread"); this.socket = socket; }
Version 1 CalcThread (2) - pseudo code public void run() { PrintWriter out = new PrintWriter(socket.getOutputStream()); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); CalcProtocol calculator = new CalcProtocol(); do { outputLine = calculator.processInput(inputLine); out.println(outputLine); if (outputLine.equals("Bye")) { break;} inputLine = in.readLine(); } while (!input.equals(“Bye")); socket.close(); }
CalcProtocol (1) – pseudo code public class CalcProtocol { // Allowed states private int WAITING_2_START = 0; private int EXPECT_OPERATOR = 1; private int EXPECT_2_NUMBERS = 2; private char operation; private String menu = "+ or – or e for Exit"; private int state = WAITING_2_START;
CalcProtocol (2) – pseudo code public String processInput(String theInput) { String theOutput = null; switch (state) { case WAITING_2_START: theOutput = returnMenu(); break; case EXPECT_OPERATOR: theOutput = processOperator(theInput); case EXPECT_2_NUMBERS: theOutput = doOperation(theInput); } return theOutput;
CalcProtocol (3) – pseudo code private String processOperator(String s) { c = s.charAt(0); switch (c) { case '+‘ and ‘-’: operation = c; out = "Enter 2 numbers: "; state = EXPECT_2_NUMBERS; break; case 'e': out = "Bye"; default: out = "not validate operator, re-enter operator: "; } return out;
CalcProtocol (4) – pseudo code private String doOperation(String s) { n1 = sc.nextInt(); n2 = sc.nextInt(); switch (operation) { case '+': out = Integer.toString(n1 + n2); break; case '-': out = Integer.toString(n1 - n2); } state=WAITING_2_START; return "Answer = " + out;
CalcClient(1) – pseudo code public class CalcClient { public static void main(String[] args) { String hostName = "localhost"; int port = 5555; Socket socket = new Socket(hostName, port); PrintWriter out = new PrintWriter(socket.getOutputStream()); Scanner in=new Scanner(socket.getInputStream()); Scanner stdIn = new Scanner(System.in); About connect And set up the input out streams
CalcClient(2) – pseudo code About receive msg while (true) { fromServer = in.nextLine(); println("Server says: " + fromServer); if (fromServer.equals("Bye")) break; fromUser = stdIn.nextLine(); println("Client says: " + fromUser); out.println(fromUser); } // while out.close(); in.close(); stdIn.close(); socket.close(); } About send msg About disconnect
Version 2 : Adding GUI to the client No need to change the server side at all Version 1: CalcClient mixture of IO with user and communication with the server Version 2: separate IO with user from the communication with the server: CalcClient2: communicate with server CalcClientGUI: communicate with user
Version 2 : Adding GUI to the client CalcClient2: change the main into some specific methods: Connect Disconnect Send Receive CalcClientGUI: IO with user is done via a JFrame; it drives CalcClient2 2018/6/15 Client-server programming
Revised structural design on client side 2018/6/15 Client-server programming
Implementation – version 2 with GUI
CalcClient2(1) – pseudo code public class CalcClient2 { private String hostName = "localhost"; private int port = 5555; private Socket socket = null; private PrintWriter out = null; private Scanner in = null; // from server private Scanner stdIn = new Scanner(System.in); private String fromServer; private String fromUser;
CalcClient2(2) – pseudo code public void connect() { socket = new Socket(hostName, port); out = new PrintWriter(socket.getOutputStream()); in = new Scanner(socket.getInputStream()); } public void disconnect() { out.close(); in.close(); stdIn.close(); socket.close(); 2018/6/15 Client-server programming
CalcClient2(3) – pseudo code public void sendToServer(String msg) { out.println(msg); } public String receiveFromServer() { return in.nextLine(); 2018/6/15 Client-server programming
CalcClientGUI Use Netbeans Form editor to create the interface (demo) For each event, implement the appropriate event handler. In the event handler, call the corresponding methods in CalcClient2 to communicate with the serever (I.e. Linking the GUI to the client and therefore the server.)
Linking the GUI to CalcClient2 Change this: private void connectButtonActionPerformed( java.awt.event.ActionEvent evt) { // TODO add your handling code here: } To: client.connect(); String msg = client.receiveFromServer(); serverTextArea.setText(msg); 2018/6/15 Client-server programming