TCP Socket auf Verbindungsabbruch prüfen

Fohnbit

Top Contributor
Hallo!

Ich baue und halte einen TCP Socket aufrecht.
Nun kann aber sein, das manchmal über Minuten/Stunden keine Daten gesendet werden müssen.

Aber mich muss dennoch einen Verbindungsabbruch erkennen.
Aber darf keine Daten über den Socket senden, sonst reagiert die Gegenseite.
Ich sende Daten über den Socket mit einer InnerClass:
Java:
/** Inner class representing the Consumer side */
    class Consumer extends Thread {

        public void run() {
            while (true) {
                byte[] b = null;
                synchronized (list) {
                    while (list.size() == 0) {
                        try {
                            // System.out.println("CONSUMER WAITING");
                            list.wait(); // must own the lock
                        } catch (InterruptedException ex) {
                            System.out.println("CONSUMER INTERRUPTED");
                        }
                    }
                    b = list.removeLast();
                    list.notifyAll();
                    // int len = list.size();
                    // System.out.println("List size now " + len);
                    // if (done)
                    // break;
                }

                long timeDifference = (lastTransmissionTime + getPropertyDelayout()) - System.currentTimeMillis();

                if (timeDifference > 0) {
                    try {
                        // System.out.println("Sleep " + timeDifference);
                        Thread.sleep(timeDifference);
                    } catch (InterruptedException e) {

                        e.printStackTrace();
                    }

                }

                process(b); // Outside synch section (could take time)
                // yield(); DITTO
            }
        }

        void process(byte[] b) {
            try {
                if (b == null || getOutputState() != 3) {
                    return;
                }
                lastTransmissionTime = System.currentTimeMillis();
                socket1.getOutputStream().write(b);

            } catch (Exception e) {
                updateOutputError("[ERROR] Sending Message: " + e.getMessage());
                if (shouldBeConnected) {
                    reConnect();
                } else {
                    disconnect(false, false);
                }

            }

        }
    }

Daten empfange ich vom Socket über einen Thread:
Java:
public void run() {
        InputStream is = null;
        try {
            is = socket.getInputStream();
            in = new BufferedInputStream(is);
        } catch (IOException e) {
            try {
                socket.close();
            } catch (IOException e2) {
                System.err.println("Socket not closed :" + e2);
            }
            parent.error("Could not open socket : " + e.getMessage(), false);
            parent.disconnect(false, false);
            return;
        }

        while (!desonnected) {
            try {
                byte[] got = readInputStream(in); // in.readLine();
                if (got == null) {
                    parent.error("Connection closed by client", false);
                    break;
                }
                parent.receiveNewBytes(got, false);
            } catch (IOException e) {
                if (!desonnected) {
                    parent.error(e.getMessage(), "Connection lost", false);
                }
                break;
            }
        } // end of while
        try {
            is.close();
            in.close();

        } catch (Exception err) {
        }
        socket = null;
    }// end of run
 
Wieso reicht dir das denn nicht aus wenn der Verbindungsabbruch erst beim Senden stattfindet?
Du kannst ja dann immernoch die Verbindung neu aufbauen und die Datei nach dem Neuaufbau versenden.
 
Bei TCP hast du ja eine virtuelle Verbindung, da gibt es bestimmt Mittel & Wege.
Außerdem kannst du alle x Sekunden einen Heart Beat zum Server senden.
 
Man könnte noch einen Timeout setzen, wenn innerhalb dieses Zeitraumes keine Daten empfangen wurden, wird ein Heart Beat gesendet.
Anders scheint es ja nicht zu gehen.
 
In dem Fall kann man die keep-alive Funktion aktivieren mittels "Socket.setKeepAlive(true)". Ausserdem sollte man noch die Zeit bis zum Senden von keep-alive Paketen verkürzen. Unter Windows mit HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime und in Linux mit /proc/sys/net/ipv4/tcp_keepalive_time.
 
Das keep-alive was optional ist und ein umkomfigurieren des Rechners erfordert (was andere Applications dann auch wieder überschreiben können...) und auch nicht von allen Netzwerkstacks unterstützt wird? Klingt immer super 😉

warum fügt man dem Protocol nicht einfach einen Heartbeat hinzu?
 

Neue Themen


Zurück
Oben