Bio: fds kaputter tcp-verbindungen "recyclen" - wie?

Sup!

Aus irgendeinem, nicht wirklich wichtigen Grund schreibe ich eine Art von Server (ein Dingens, das tcp-connections annehmen kann).
Dieser Server kann eine bestimmte Anzahl (sagen wir mal zum Beispiel 4, eigentlich sind es eher 1024) Verbindungen annehmen.
Es ist wichtig, dass er diese 4 Verbindungen immer annehmen kann.
Es ist allerdings moeglich und sogar einigermassen wahrscheinlich, dass ein oder mehrere Kommunikationspartner einen tragischen Systemcrash haben und sich neu verbinden muessen.
Und unguenstigerweise hat er auch nur Speicher fuer 4 Filedeskriptoren.
Ich brauche also eine Art Garbage-Collection, damit die kaputten Verbindungen erkannt und die Filedeskriptoren wieder freigegeben werden fuer neue accepts.

Wenn man SO_KEEPALIVE setzt... und am tcp-timeout herumschraubt... dann kriegt man evtl. mit, dass die Verbindung zusammengebrochen ist, das habe ich schon mal recherchiert. ggf. sogar ziemlich schnell, innerhalb von akzeptablen Zeitraeumen.

Die Frage ist aber: Kriegt man eine Exception, wenn man ein select auf die verdaechtigen Deskriptoren macht, wenn der Timeout abgelaufen ist?
Oder muss man ein read versuchen, und bekommt dann 0 zurueck, und ggf. einen Socket Error, den man sich mit getsockopt holen muss, oder beides?

Irgendwie wollen die man-pages sich da nicht wirklich klar zu aeussern,

(HILFEEEEE! ;-) )

Gruesse,

Bio

--
Elite ist mein zweiter Vorname
  1. Hallo Bio,

    Die Frage ist aber: Kriegt man eine Exception, wenn man ein select auf die verdaechtigen Deskriptoren macht, wenn der Timeout abgelaufen ist?
    Oder muss man ein read versuchen, und bekommt dann 0 zurueck, und ggf. einen Socket Error, den man sich mit getsockopt holen muss, oder beides?

    ich hab' mal in alten Sourcen von mir gewühlt. Ich habe bei einem Server dabei folgendermaßen auf Verbindungs-Abbrüche reagiert:

    1. Wenn read() auf einen Socket mit Returncode < 0 zurückkommt, liegt ein Fehler auf dem Socket vor. Reaktion: dazugehörenden fd schließen. Den Fehlercode habe ich aus errno ausgelesen.

    2. Returncode 0 bei read() heisst nur EOF; die Verbindung kann trotzdem noch bestehen.

    3. Ich habe das Signal SIGPIPE abgefangen. SIGPIPE wird an den Prozess gesendet, der mit dem Socket verbunden ist, falls nicht mehr auf einen Socket geschrieben werden kann. Reaktion wie bei 1.

    Der Server war so designed, dass jede Verbindung in einem eigenen Prozess behandelt wurde. I.d.R. warteten die Prozesse dabei auf einem read() auf Daten der Clients. Wurde die Verbindung unterbrochen, kehrte der read() mit einem Returncode < 0 zurück.

    SO_KEEPALIVE habe ich in der ganzen Anwendung nicht benötigt.

    Viele Grüße
    Frank