Frage

Ich denke, dass ich die formale Bedeutung der Option verstehen. In einigen Legacy-Code jetzt bin ich der Handhabung, wird die Option verwendet. Der Kunde beschwert sich über RST als Antwort auf FIN von seiner Seite auf der Verbindung nahe von seiner Seite.

Ich bin nicht sicher, kann ich es sicher entfernen, da verstehe ich nicht, wenn es verwendet werden soll.

Können Sie bitte ein Beispiel geben, wenn die Option erforderlich wäre?

War es hilfreich?

Lösung

Der typische Grund für eine SO_LINGER Timeout von Null zu setzen, ist ein große Anzahl von Verbindungen zu vermeiden, in dem TIME_WAIT Zustand sitzen, alle auf einem Server zur Verfügung stehenden Ressourcen zu binden.

Wenn eine TCP-Verbindung sauber geschlossen ist, das Ende, das die engen eingeleitet ( „active close“) endet mit der Verbindung in TIME_WAIT für einige Minuten sitzen. Also, wenn Ihr Protokoll ist ein, wo die Server initiiert die Verbindung zu schließen, und eine sehr große Anzahl von kurzlebigen Verbindungen beinhalten, dann könnte es für dieses Problem anfällig sein.

Das ist keine gute Idee, wenn auch - TIME_WAIT aus einem Grunde besteht (das Streu Pakete von alten Verbindungen, um sicherzustellen, nicht mit neuen Verbindungen stören). Es ist eine bessere Idee, um Ihr Protokoll ein, wo der Client initiiert die Verbindung nahe neu zu gestalten, wenn möglich.

Andere Tipps

Für meinen Vorschlag, bitte den letzten Abschnitt lesen. „Wenn SO_LINGER mit Timeout 0 verwenden“

Bevor wir kommen, dass ein wenig Vortrag über:

  • Normale TCP Beendigung
  • TIME_WAIT
  • FIN, ACK und RST

Normale TCP Beendigung

Die normalen TCP-Terminierungssequenz sieht wie folgt aus (vereinfacht):

Wir haben zwei Kollegen: A und B

  1. A ruft close()
    • A sendet FIN an B
    • A geht in FIN_WAIT_1 Zustand
  2. B empfängt FIN
    • B sendet ACK bis A
    • B geht in CLOSE_WAIT Zustand
  3. A empfängt ACK
    • A geht in FIN_WAIT_2 Zustand
  4. B ruft close()
    • B sendet FIN bis A
    • B geht in LAST_ACK Zustand
  5. A empfängt FIN
    • A sendet ACK an B
    • A geht in TIME_WAIT Zustand
  6. B empfängt ACK
    • B geht an CLOSED Zustand - das heißt aus dem Sockel Tabellen entfernt

TIME_WAIT

So der Peer dass Eingeweihte die Kündigung - das heißt Anruf close() ersten -. Wird bis im TIME_WAIT Zustand beenden

Um zu verstehen, warum der TIME_WAIT Zustand ist unser Freund, bitte Abschnitt 2.7 in "UNIX Network Programming" dritte Auflage von Stevens et al (Seite 43) gelesen werden.

Allerdings kann es ein Problem mit vielen Steckdosen in TIME_WAIT Zustand auf einem Server sein, da es schließlich neue Verbindungen verhindern könnte von akzeptiert werden.

Um dieses Problem umgehen, ich habe viele gesehen, die SO_LINGER Socket-Option mit Timeout 0 vor dem Aufruf close() einstellen läßt. Dies ist jedoch eine schlechte Lösung, da es die TCP-Verbindung führt mit einem Fehler abgebrochen werden.

Stattdessen entwerfen Sie Ihr Anwendungsprotokoll, so dass der Verbindungsabbruch immer von der Client-Seite initiiert wird. Wenn der Kunde weiß immer, wenn es alle verbleibenden Daten lesen kann er die Terminierungssequenz einzuleiten. Als Beispiel weiß ein Browser aus dem Content-Length HTTP-Header, wenn es alle Daten gelesen hat und die enge initiieren kann. (Ich weiß, dass in HTTP 1.1 wird es hält es für eine Weile für eine mögliche Wiederverwendung öffnen und schließen Sie es.)

Wenn der Server braucht die Verbindung zu schließen, gestalten das Anwendungsprotokoll, damit der Server den Client Aufruf close() fragt.

Wann verwendet SO_LINGER mit Timeout 0

Auch nach "UNIX Network Programming" dritte Auflage Seite 202-203, Einstellung SO_LINGER mit Timeout 0 vor close() des Aufrufs wird die normale Beendigung Sequenz verursachen nicht eingeleitet werden.

Stattdessen wird die Peer diese Option Einstellung und close() Aufruf wird eine RST (Verbindung zurückgesetzt) ??senden, die anzeigt, einen Fehlerzustand und dies ist, wie wird es am anderen Ende wahrgenommen werden. Sie werden in der Regel Fehler wie „Verbindung von Peer zurückgesetzt“ sehen.

Daher wird in der normalen Situation ist es eine wirklich schlechte Idee, Satz SO_LINGER mit Timeout 0 vor dem Aufruf close() - von nun an genannt gescheiterten schließen -. In einer Server-Anwendung

Allerdings sind bestimmte Situation erfordert dabei trotzdem:

  • Wenn der Kunde von der Serveranwendung misbehaves (Timeout, kehrt ungültige Daten, etc.) eine gescheiterte Nähe Sinn macht in CLOSE_WAIT oder enden im TIME_WAIT Zustand befindet, stecken zu vermeiden.
  • Wenn Sie Ihre Server-Anwendung neu starten müssen, die derzeit Tausende von Client-Verbindungen hat man bedenkt, könnte diese Socket-Option Einstellung zu vermeiden Tausende von Server-Sockets in TIME_WAIT (beim Aufruf close() vom Server Ende), da dies den Server von immer verfügbaren Ports für neue Client-Verbindungen verhindern, nachdem neu gestartet werden.
  • Auf Seite 202 in dem oben erwähnten Buch sagt es ausdrücklich: „Es gibt bestimmte Umstände, die die Verwendung diese Funktion garantieren eine gescheiterte Nähe senden Ein Beispiel ist ein RS-232-Terminal-Server, der für immer in CLOSE_WAIT hängen könnte versuchen, Daten zu liefern. zu einem festgefahrenen Terminal-Anschluss, würde aber das steckt Port korrekt zurückgesetzt, wenn er ein RST bekam die anstehenden Daten. "
  • zu verwerfen

Ich würde empfehlen,

Ob Sie die linger in Ihrem Code sicher zu entfernen oder nicht, hängt von der Art der Anwendung: es ist ein „Client“ (Öffnung TCP-Verbindungen und aktiv erste Schließung) oder ist es ein „Server“ (hört ein TCP offen und es nach der anderen Seite schließen eingeleitet, um die Nähe)?

Wenn Ihre Anwendung hat den Geschmack eines „Client“ (Schluss zuerst) und Sie initiieren und in der Nähe eine große Anzahl von Verbindungen zu verschiedenen Servern (zB wenn Ihre Anwendung ist eine Überwachung der App die Erreichbarkeit einer großen Anzahl von verschiedenen Servern überwacht ) Ihre Anwendung hat das Problem, dass alle Ihre Client-Verbindungen in TIME_WAIT Zustand stecken. Dann würde ich empfehlen, noch Abschaltung anmutig das Timeout auf einen kleineren Wert als die Standardeinstellung zu verkürzen, aber die Client-Verbindungen Ressourcen früher frei. Ich würde das Timeout nicht auf 0 gesetzt, da 0 nicht Abschaltung graziös mit FIN aber gescheiterten mit RST.

Wenn Ihre Anwendung den Geschmack eines „Client“ und hat eine große Anzahl von kleinen Dateien aus dem gleichen Server zu holen, sollten Sie nicht eine neue TCP-Verbindung pro Datei initiieren und in einer riesigen Menge von Client-Verbindungen am Ende in TIME_WAIT, aber halten Sie die Verbindung offen und alle Daten über die gleiche Verbindung holen. Linger Option kann und sollte entfernt werden.

Wenn Ihre Anwendung ein „Server“ ist (an zweiter Stelle als Reaktion auf Peers schließen), auf close () Ihre Verbindung Abschaltung anmutig und Ressourcen befreit werden, wie Sie nicht TIME_WAIT-Zustand. Linger sollten nicht verwendet werden. Aber wenn Ihr Sever App einen Überwachungsprozess Erkennung inaktive offene Verbindungen idleing für eine lange Zeit hat ( „long“ ist definiert werden) Herunterfahren kann diese inaktive Verbindung von Ihrer Seite - sieht es als eine Art Fehlerbehandlung - mit einem mißglückten Abschaltung. Dies geschieht durch linger Timeout auf 0 Schließen () wird dann ein RST an den Client senden, ihm zu sagen, dass Sie sind wütend: -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top