How to stop scheduleAtFixedRate after the condition fails

75 Views Asked by At

I have a problem -

Statement: I will be sending data from the client to the server and the server would be responding back with some data to the client after it receives the message from the client. The data that will be sent to the server will be sent in the certain frequency, and if I don't get the reply from the server in certain timeout, I should be displaying the message in my client that the "server is stateless and is not working".

Below is my code and questions:


package com.soc;
import java.io.*;
import java.net.*;
import java.util.Timer;
import java.util.TimerTask;

public class LocalFaultDetector {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Timer timer = new Timer();
        int heartbeatFreq = 3000; // Configure your default frequency in milliseconds
        String serverIP = "localhost"; // Replace with the IP address of your server
        int serverPort = 8999; // Replace with the port your server is listening on
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try(Socket socket = new Socket(serverIP, serverPort)) {

                    // Send the message to Server
                    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                    out.println("Message from client to the server");

                    // Print sending message on LFD1 console
                    System.out.println("Sent message to server with the message");

                    // Set a timeout for reading the response
                    socket.setSoTimeout(timeout);
            //IF THE TIMEOUT IS CROSSED, HOW DO I EXIT THE scheduleAtFixedRate loop.
                    // Read the response from the server
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String serverResponse = in.readLine();
                    if(serverResponse != null){
                        System.out.println("Received response from server: " + serverResponse);
                    } else {
                        System.err.println("No response received from the server within the timeout.");
                    }
                } catch (SocketTimeoutException e) {
                    System.err.println("Timeout waiting for a response from the server.");
                } catch (IOException e) {
                    // Handle exceptions (e.g., server not responding)
                    System.err.println("Error: " + e.getMessage());
                }
            }
        }, 0, heartbeatFreq);
    }
}

My questions:

  1. If the timeout is crossed in socket.setSoTimeout(timeout);, how do I exit/break/close/cancel the scheduleAtFixedRate so that the client does not send the message to the server again?

  2. Is there any other optimal way to send the message from the client to the server in frequencies (ie. every 5 seconds) and wait for the reply from the server and check if I get the messages back from the server. Any suggestions would be helpful.

I have tried my best and I am very new to the network programming. Above is the code that I have tried.

1

There are 1 best solutions below

0
lant On

TimerTask has a cancel method

Cancels this timer task. If the task has been scheduled for one-time execution and has not yet run, or has not yet been scheduled, it will never run. If the task has been scheduled for repeated execution, it will never run again. (If the task is running when this call occurs, the task will run to completion, but will never run again.)

so you can cancle the task when SocketTimeoutException occurs.

catch (SocketTimeoutException e) {
      System.err.println("Timeout waiting for a response from the server.");
      cancel();
}

There is another way to implement scheduled tasks, can achieve more complex functions, for simple tasks,Timer is enough.

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    executor.scheduleAtFixedRate(() -> {
        try {
        } catch (Exception e) {
            executor.shutdown();
        }
    }, 0, 5, TimeUnit.SECONDS);