Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-reconnect to a server using a socket in Java

There is a component in my application that listens to a server via TCP (so it only receives data, the output-stream is never used). The only reason for a potential disconnect are technical issues. From a logical point of view, the connection should stay open forever.

I know that I have to implement some kind of ping/pong strategy if I want to detect a connection failure immediately. But in my case, it is not necessary to detect a dropped connection immediately as long as it gets detected at all (let's say some minutes or hours later).

My questions:

  1. If I don't use some kind of pingpong/alive-check strategy and the connection drops, will I get an IOException in my application logic some time later (it would be okay if it took some hours) or is it possible that the dropped connection isn't detected at all?
  2. Would the code below fit my requirements? It's a bit ugly (many try-catch/while(true) and even sleep, but I'm wondering if a timed out connection could be recognized after a certain amount of time (e.g. due to an IOException in the blocking BufferedReader.readLine method).
  3. Apart from the questions above, what could I do better?

    public class Receiver implements Runnable {
    
    private Socket socket;
    private final String host;
    private final int port;
    private final int connectionRetryAfter = 10* 1000;
    
    public Receiver(String host, int port)  { // assignments... }
    
    @Override
    public void run() {
        tryCreateSocket();
        listenToServer();
    }
    
    private void listenToServer() {
        String receivedLine;
        BufferedReader buf;
        while(true) {
            try {
                buf = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while ((receivedLine = buf.readLine()) != null) {
                    // do something with 'inputLine'
                }
            } catch (IOException e) {
                // logging
            } finally {
                closeSocket();
            }
            // At this point, either an exception occured or the stream equals null (which means it's closed?)
            tryCreateSocket();
        }
    }
    
    private void tryCreateSocket() {
        try {
            socket = new Socket(host, port);
        } catch (IOException e) {
            // logging
            try {
                Thread.sleep(connectionRetryAfter);
            } catch(InterruptedException ex) {
                // logging
                Thread.currentThread().interrupt();
            }
            // retry
            tryCreateSocket();
        }
    }
    
    private void closeSocket() {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                // logging
            }
        }
    }
    

    }

like image 972
alapeno Avatar asked Mar 10 '26 21:03

alapeno


1 Answers

listenToServer() should certainly throw an IOException if the connection/reconnection attempt fails. Consider the case when the server is down. Do you really want to loop inside this method forever?

like image 76
user207421 Avatar answered Mar 12 '26 09:03

user207421



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!