I’ve built simple client-server model using sockets. The server receives 1 type of request: 2 numbers from client, sums them, waits for 5 seconds and sends the response back to the client. I’m trying to send 20 asynchronous request from the client without waiting for response. The client should sums all the numbers from all the 20 Reponses from server. I’m trying to understand what should I use and how? Threads on the server, or the client and how? I’ve added my client and server classes. Server:
public class Server { public static void main(String[] args) throws IOException { try { //Make a ServerSocket to listen for message ServerSocket ss = new ServerSocket(7777); while (true == true) { //Accept input from socket Socket s = ss.accept(); //Read input from socket InputStreamReader streamReader = new InputStreamReader(s.getInputStream()); BufferedReader reader = new BufferedReader(streamReader); String message = reader.readLine(); System.out.println(message); //parse the json recieved from client and sum the 2 numbers Object obj = new JSONParser().parse(String.valueOf(message)); JSONObject jo = (JSONObject) obj; long num1 = (long) jo.get("num1"); long num2 = (long) jo.get("num2"); long sum = num1 + num2; Thread.sleep(5000); //putting response as json JSONObject jsonResponse = new JSONObject(); jsonResponse.put("response", sum); //get the message and write it to the socket as response PrintWriter writer = new PrintWriter(s.getOutputStream()); writer.println(jsonResponse); //System.out.println(df); writer.close(); } } catch (IOException | ParseException | InterruptedException ex) { System.out.println(ex); } } }
Client:
public class Client { public static void main(String[] args) throws IOException { try { //this variable will sum all the responses from server long sumOfAllResponses = 0; for(int i = 0 ; i< 20; i++){ //Create a Socket with ip and port number Socket s = new Socket("localhost", 7777); Scanner in = new Scanner(System.in); PrintWriter writer = new PrintWriter(s.getOutputStream()); InputStreamReader streamReader = new InputStreamReader(s.getInputStream()); BufferedReader reader = new BufferedReader(streamReader); //Creating json with 2 numbers to be sent to server as a request JSONObject jsonRequest = new JSONObject(); jsonRequest.put("num1", 1); jsonRequest.put("num2", 1); System.out.println(jsonRequest); //Make a printWriter and write the message to the socket writer.println(jsonRequest); writer.flush(); //Get the response message from server String responseMessage = reader.readLine(); //parse the response and add the result to the sum variable Object obj = new JSONParser().parse(String.valueOf(responseMessage)); JSONObject jo = (JSONObject) obj; sumOfAllResponses += (long) jo.get("response"); } System.out.println(sumOfAllResponses); } catch (IOException | ParseException ex) { ex.printStackTrace(); // (**) } } }
Advertisement
Answer
Asynchronous means sending message and not waiting for response.
//Get the response message from server - so you wait whole 5 seconds for response :) String responseMessage = reader.readLine();
The simplest solution in this case is to remove waiting for response each time. So, get rid of above lines from loop inside Client class.
In this particular client-sever case you do not need additional threads, if you would perform asynchronous things inside one application, then so. Take a look at Java Futures with some tutorial on how to use them. But if you want to get a result from server, you have to wait anyway. And you want to get results of all calcuations. Hence, you have to store all incoming requests somewhere. Simple, naive and impractical, but showing asynchronicity concept code may look like this
public class Client { public static void main(String[] args) throws IOException { try { long start = System.currentTimeMillis(); BufferedReader reader = null; for(int i = 0 ; i < 20; i++){ Socket s = new Socket("localhost", 7777); PrintWriter writer = new PrintWriter(s.getOutputStream()); InputStreamReader streamReader = new InputStreamReader(s.getInputStream()); reader = new BufferedReader(streamReader); // just make sure you send data and do not wait for response System.out.println("Sending " + i + " : " + (System.currentTimeMillis() - start)); writer.println(i); writer.flush(); } //this line works like future.get(), it hangs client until it receives result String responseMessage = reader.readLine(); // process returned data as you want System.out.println(responseMessage); } catch (IOException ex) { ex.printStackTrace(); // (**) } } } public class Server { public static void main(String[] args) throws IOException { try { //Make a ServerSocket to listen for message ServerSocket ss = new ServerSocket(7777); Socket s; //we need to store incoming requests to process, and return them List<String> integerList = new LinkedList<>(); while (true) { s = ss.accept(); InputStreamReader streamReader = new InputStreamReader(s.getInputStream()); BufferedReader reader = new BufferedReader(streamReader); String message = reader.readLine(); System.out.println(message); // do something here Thread.sleep(5000); PrintWriter writer = new PrintWriter(s.getOutputStream()); integerList.add(message); writer.println(integerList); writer.close(); } } catch (IOException | InterruptedException ex) { System.out.println(ex); } } }