Question

There's a while loop in Client class where I ask user to make some calculations.The problem appears when I try to make more than one calculation. It stucks on making the calculation from Server class.

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

public class Client {

private static final int PORT = 1234;

public static void main(String[] arg) {
  try {

      Scanner userInputScanner = new Scanner(System.in);

      Calculator c = new Calculator(0,0,"+");
      CalculatorProtocol s = new CalculatorProtocol();
      String testString = null;
      String answer = null;

      Socket socketConnection = new Socket(InetAddress.getLocalHost(),PORT);
      ObjectOutputStream clientOutputStream = new
              ObjectOutputStream(socketConnection.getOutputStream());
           ObjectInputStream clientInputStream = new 
              ObjectInputStream(socketConnection.getInputStream());

      do{

         System.out.println("Give the 1st integer:");
         testString = userInputScanner.next();
         while (!s.isInteger(testString)) {
             System.out.println("Wrong input data." + "Give the 1st integer:");
             testString = userInputScanner.next();
         }
         c.setFirstNumber(Integer.parseInt(testString));            

         System.out.println("Give the 2nd integer:");
         testString = userInputScanner.next();

         while (!s.isInteger(testString)) {
             System.out.println("Wrong input data." + "Give the 2nd integer:");
             testString = userInputScanner.next();
         }                   
         c.setSecondNumber(Integer.parseInt(testString));
         userInputScanner.nextLine(); // Gia na mi ginei lathos

         System.out.println("Give the operator (+,-,*,/):");
         testString = userInputScanner.nextLine();
         while(!s.isOperator(testString)) {
            System.out.println("Wrong input data."                          
                    + "Give the operator(+,-,*,/):");
            testString = userInputScanner.next();
         }
        c.setOperation(testString);

        System.out.println("First integer:" +c.getFirstNumber());
        System.out.println("Second integer:" +c.getSecondNumber());
        System.out.println("Operator:"+c.getOperation());                   

      clientOutputStream.writeObject(c);

      c = (Calculator)clientInputStream.readObject();


      System.out.println("Result="+c.getResult());

      System.out.println("Want more?");          
      answer = userInputScanner.nextLine();
      }while(s.wantMore(answer));

      clientOutputStream.close();
      clientInputStream.close();



  }catch (Exception e) {System.out.println(e); }
        }
}

Server Class

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

public class Server {

  private static final int PORT = 1234;

  public static void main(String[] arg) {

  Calculator c = null;
  CalculatorProtocol s = new CalculatorProtocol();
  String answer = null;



      try {
              ServerSocket socketConnection = new ServerSocket(PORT);

              System.out.println("Server Waiting");


              while(true) {
                  Socket pipe = socketConnection.accept();
                  ObjectInputStream serverInputStream = new    
                                   ObjectInputStream(pipe.getInputStream());

                         ObjectOutputStream serverOutputStream =   new 
                                    ObjectOutputStream(pipe.getOutputStream());
                       c =    (Calculator)serverInputStream.readObject();
                     while (true) {


                        c.setResult(s.Calculate(c.getFirstNumber(), c.getSecondNumber()
                                , c.getOperation() ));
                        serverOutputStream.writeObject(c);

                     }



              }




          }  catch(Exception e) {System.out.println(e); 
  }


  }
}

Class for the protocol

public class CalculatorProtocol  {


private int a , b ;
private String d;




public static boolean isInteger(String str) {
    if (str == null) {
        return false;
    }
    int length = str.length();
    if (length == 0) {
        return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
        if (length == 1) {
            return false;
        }
        i = 1;
    }
    for (; i < length; i++) {
        char c = str.charAt(i);
        if (c <= '/' || c >= ':') {
            return false;
        }
    }
    return true;
}

public boolean isOperator(String op){
    if(!(op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/")))
         return false;
    else
        d = op;
        return true;
}

public int Calculate(int n1 , int n2 , String o) {

    a = n1;
    b = n2;
    d = o;

    int result = 0;

    if (d.equals("+"))
        result = a + b;
    else if (d.equals("-"))
        result = a - b;
    else if (d.equals("*"))
        result = a * b;
    else 
        result = a/b;

    return result;
}

public boolean wantMore(String m){
    if (m.equals("Yes"))
        return true;
    else
        return false;
}



}



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

public class Calculator implements Serializable {

private int num1,num2,result;
private String calc;

Calculator class for calculator objects.

Calculator (int a, int b, String p) {
  num1 = a;
  num2 = b;
  calc = p;
  result = 0;

}

public int getFirstNumber() {
  return num1 ;
}

public int getSecondNumber() {
    return num2 ;
 }

public void setFirstNumber(int num) {
  num1 = num;
}

public void setSecondNumber(int num) {
      num2 = num;
   }

public String getOperation() {
  return calc ;
}

public void setOperation(String op) {
  calc = op;
}

public void setResult(int d) {
   result = d;
}

public int getResult() {
   return result;
}
}
Was it helpful?

Solution

Without sifting through all of your posted code, I will diagnose your question. It seems like you want to add more than one client to do a calculation. It gets stuck here.

while(true) {
    Socket pipe = socketConnection.accept();
    ObjectInputStream serverInputStream = new ObjectInputStream(pipe.getInputStream());

    ObjectOutputStream serverOutputStream = new ObjectOutputStream(pipe.getOutputStream());
    c =    (Calculator)serverInputStream.readObject(); //this is only done once
    while (true) { // you need logic to break out of this loop.
        c.setResult(s.Calculate(c.getFirstNumber(), c.getSecondNumber(), c.getOperation() ));
        serverOutputStream.writeObject(c); //this is done multiple times
    }

Assuming you only want to handle one client at a time, what you want to do is take calculations from that client until it no longer wants to send them. And then assuming you will take in one object and then write one object and rinse and repeat, what you need to do change is the following.

    ObjectInputStream serverInputStream = new ObjectInputStream(pipe.getInputStream());
    ObjectOutputStream serverOutputStream = new ObjectOutputStream(pipe.getOutputStream());
    while (true) { 
        c =    (Calculator)serverInputStream.readObject();
        c.setResult(s.Calculate(c.getFirstNumber(), c.getSecondNumber(),c.getOperation() ));
        serverOutputStream.writeObject(c);
    }

You need to add some logic to break out of that loop based on a client leaving though, or will cycle forever.

OTHER TIPS

The Server is writing c over and over while in the loop waiting for client input.

Upon the next calculation, the client isn't getting an updated version of c. To get a fresh copy of an updated object you need to call serverOutputStream.reset()

ObjectStreams add a reference for each object that has been written to it. You will need to call reset which removes all references of previously written objects. Enabling you to send an edited copy.

The main concern is how you are sending the object in the loop from the server. You are constantly sending it in a forever true loop in rapid succession.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top