# Wiederverbinden nach socket Abbruch



## Fohnbit (16. Sep 2015)

Hallo!

Mir macht die Strategie beim reconnect eines socket Abbruchs etwas Schwierigkeiten.
socket1
Es gibt 1 Methode die den Verbindungsaufbau initieren:
onStart(boolean)

socket2
Bei jedem Verbindungsaufbau muss zuerst ein config befehl über einen anderen Socket gesendet werden.
Dafür muss socket1 beenden, socket2 starten, config senden, socket2 schließen und nach 4 Sekunden socket1 wieder starten.

socket1
Wenn der Verbindungsaufbau scheitert oder beim senden Fehler entstehen, soll ein reconnect nach 10 Sekunden erfolgen, welcher immer im Loop läuft, bis die verbindung wieder steht oder onStop ausgeführt wird.

Die Sockets habe ich fertig. Einzig die Strategie für den reconnect fehlt mir.


```
public void onStart(boolean value) {
        if (value) {
            shouldBeConnected = true;
            connect();
        } else {
            shouldBeConnected = false;
            disconnect(false, false);
        }
    }
```


```
public synchronized void disconnect(boolean reconnect,
            boolean controlMessage) {
        System.out.println("Disconnect, reconnect: " + reconnect);
       
        // Debug Ausgabe
        updateOutputState(EnumAutostartState.Stopping.getNumVal());

        // Falls der Reconnect Timer läuft, abbrechen
        if (reconnectTimer != null) {
            reconnectTimer.cancel(true);
            reconnectTimer = null;
        }

        // Wenn der Socket existiert
        if (socket1 != null) {

            try {
                socketClient.setDesonnected(true);
                socket1.close();
            } catch (Exception e) {
                updateOutputError("[ERROR] Closing USB-2: " + e);
                // System.err.println("Error closing client : " + e);
            }
        }
        socket1 = null;
        updateOutputState(EnumAutostartState.Stopped.getNumVal());
        if (shouldBeConnected) {
            executor.schedule(new Runnable() {
                public void run() {
                    connect();
                }
            }, 500, TimeUnit.MILLISECONDS);
        }

    }

    private void connect() {
        System.out.println("Connect.");
       
        // Wenn gar nicht verbunden sein soll, abbrechen
        if (!shouldBeConnected) {
            return;
        }
       
        // Wenn verbunden, zuerst trennen und neu verbinden
        if (socket1 != null) {
            disconnect(true, false);
            return;
        }

        // Neue Einstellungen senden
        generateSendControlParameter();

        // Debug Ausgabe
        updateOutputState(EnumAutostartState.Starting.getNumVal());

        String ip = inetAddress.getHostAddress();
        int port = 28880;
        if (!Util.checkHost(ip)) {
            updateOutputError("[ERROR] Destinantion not reachable!");
            updateOutputState(EnumAutostartState.Failed.getNumVal());
            reConnect();
            return;
        }

        try {

            // System.out.println("Connectig in normal mode : " + ip + ":"
            // + portNo);
            socket1 = new Socket();
            socket1.connect(new InetSocketAddress(ip, port), 2000);

        } catch (Exception e) {
            e.printStackTrace();
            updateOutputError("[ERROR] Opening Connection: " + e.getMessage());
            updateOutputState(EnumAutostartState.Failed.getNumVal());
            reConnect();
            return;
        }

        socketClient = new SocketClient(this, socket1);
        updateOutputState(EnumAutostartState.Running.getNumVal());

    }
```


```
private void reConnect() {

        if (!shouldBeConnected) {
            return;
        }

        if (reconnectTimer != null) {
            reconnectTimer.cancel(true);
            reconnectTimer = null;
        }

        reconnectTimer = executor.schedule(new Runnable() {
            public void run() {
                System.out.println("start Timer Reconnect");
                connect();
            }
        }, retryToStartDelay, TimeUnit.MILLISECONDS);
```


----------



## BuckRogers (18. Sep 2015)

Hi,

du kannst dir mit einer Klassenvariable merken an welcher Stelle die Verbindung/Verbindungsaufbau gerade steht. 
Wenn du jedoch jetzt einfach die connct()-Methode aufrufst, dann geht die ganze PRozedur von vorn los. Das willst du ja nicht, wenn du zum Beispiel die ConfigDaten schon gesendet hast. Mit deinem momentanen Aufbau der Klasse ist das nicht möglich. Du solltest dafür sorgen, dass eine Methode IMMER nur genau eine Aufgabe übernimmt. Dann hast du eine "Hauptmethode" in deiner Klasse die einfach die anderen Methoden nur aufruft und Parameter übergibt etc. Somit trennst du fein säuberlich die Zuständigkeiten innerhalb der Klasse.

Du solltest wenn versuchen immer alle Fehler mit Exceptions abzufangen und dann geeignete Maßnahmen einleiten um den Fehler zu behandeln. Wenn beispielsweise das senden der Configuration geklappt hat, aber der Aufbau der neuen Socketverbindung scheitert, dann fängst du diese Exception ab (in deiner Hauptmethode) und kannst dort zu Beispiel eine Schleife einbauen, welche alle 10 Sekunden versucht diese Socketverbindung wieder herzustellen. 

Gruß


----------

