Welcher Socket-Fehler bekomme ich, wenn TCP keep-alive die Verbindung unterbricht?

8

Ich habe eine Reihe von TCP-Sockeln mit Keep-Alive (Intervall 1 min), gesteuert von einem select(2) loop (Auswahl zum Lesen).

  • Gibt select(2) einen Fehler zurück, wenn Keep-Alive-Timeout für einen der Sockets in der Menge aufgetreten ist?
  • Welcher Fehler wird read(2) zurückgeben?
CCoder 11.12.2012, 16:25
quelle

2 Antworten

5

  • select() selbst gibt keinen Fehler zurück, wenn ein Fehler für einen der ausgewählten Sockets gemeldet wird. [Tatsächlich kann die API auf diese Weise keine Socket-Fehler anzeigen, da zwei verschiedene Sockets während eines einzelnen Aufrufs von select() jeweils einen ausstehenden Fehler erhalten könnten. Welchen würde select() zurückgeben?]
  • Nach jeder Iteration der Schleife select() verwenden Sie stattdessen das Makro FD_ISSET, um eine read() für jedes mit lesbar markierte Socket zu versuchen.
  • Jedes Mal, wenn ein Socket einen ausstehenden Fehlersatz aufweist, wird sein Leseereignis (und Schreibereignis) signalisiert und select() kehrt zurück, wodurch Sie zeitgesteuerte Fehler aufgrund von Keep-Alive sofort erkennen können. Beachten Sie, dass das Markieren eines Sockets zum Lesen nicht anzeigt, dass Daten zu lesen sind, sondern nur, dass ein Leseversuch nicht blockiert wird. Wenn der Socket einen ausstehenden Fehler hat, wird das Lesen nicht blockiert. Sowohl read(2) als auch write(2) rufen zuerst alle ausstehenden Fehler im Socket ab, bevor sie überhaupt versuchen, mit Daten umzugehen.
      

    Ein Deskriptor gilt als lesbereit, wenn ein Aufruf an eine Eingabefunktion mit O_NONBLOCK clear nicht blockiert, ob die Funktion Daten erfolgreich übertragen würde oder nicht. (Die Funktion kann Daten zurückgeben, eine Dateiendeanzeige oder einen anderen Fehler, der anzeigt, dass sie blockiert ist, und in jedem dieser Fälle gilt der Deskriptor als bereit zum Lesen.) [ POSIX: select () ]

  •   
  • Schließlich, welcher Fehler wird zurückgegeben? Entscheidend ist, dass das Keepalive fehlgeschlagen ist. Sie erhalten ETIMEDOUT , wenn das andere Ende vollständig verschwindet. Wenn ein Paketübermittlungsfehler auftritt, werden Sie dies stattdessen durchmachen (wenn also das Keep-Alive-Paket eine ICMP-Fehlerantwort erhält, wie "Host nicht erreichbar", wird EHOSTUNREACH geliefert). [Weitere Einzelheiten zu diesen Fällen finden Sie unter Stevens, "Unix Network Programming, Bd. 1".]
  •   
Nicholas Wilson 12.12.2012, 13:43
quelle
1

select() setzt ein Bit in FDSET , das anzeigt, welches Socket ausgelöst wurde. Verwenden Sie FD_ISSET Makro, um festzustellen, welcher Socket nach dem Dienst gefragt wird.

    
Wes Miller 12.12.2012 13:11
quelle

Tags und Links