Skip to content
Advertisement

How to send multiple of asynchronous requests from client to server

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 incomming 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);
    }
  }
}
Advertisement