Ordnungsgemäßes Herunterfahren, Lingeroptionen und Socketabschluss
Das folgende Material wird als Erläuterung zum Thema zum Herunterfahren von Socketverbindungen bereitgestellt, die die Sockets schließen. Es ist wichtig, den Unterschied zwischen dem Herunterfahren einer Socketverbindung und dem Schließen eines Sockets zu unterscheiden.
Das Herunterfahren einer Socketverbindung umfasst einen Austausch von Protokollmeldungen zwischen den beiden Endpunkten, nachfolgend als Abschaltungssequenz bezeichnet. Es werden zwei allgemeine Klassen von Sequenzen zum Herunterfahren definiert: ordnungsgemäß und abortiv (auch als hart bezeichnet). In einer ordnungsgemäßen Abfolge des Herunterfahrens können alle Daten, die in die Warteschlange eingereiht, aber noch nicht übertragen wurden, vor dem Schließen der Verbindung gesendet werden. Bei einem abgebrochenen Herunterfahren geht jede nicht angezeigte Daten verloren. Das Auftreten einer Sequenz zum Herunterfahren (ordnungsgemäß oder abortiv) kann auch verwendet werden, um den zugeordneten Anwendungen eine FD CLOSE-Angabe zu geben, _ die anzeigt, dass ein Herunterfahren ausgeführt wird.
Das Schließen eines Sockets bewirkt hingegen, dass die Zuordnung des Sockethandle freigegeben wird, sodass die Anwendung auf keinen Fall mehr auf den Socket verweisen oder diesen verwenden kann.
In Windows Sockets können sowohl die Shutdown-Funktion als auch die WSASendDisconnect-Funktion verwendet werden, um eine Abschaltungssequenz zu initiieren, während die Closesocket-Funktion verwendet wird, um Sockethandles freizugeben und alle zugeordneten Ressourcen freizugeben. Es entsteht jedoch ein gewisses Maß an Verwirrung durch die Tatsache, dass die Closesocket-Funktion implizit bewirkt, dass eine Abschaltungssequenz auftritt, wenn sie noch nicht erfolgt ist. Tatsächlich ist es eine recht gängige Programmierpraktiken geworden, sich auf dieses Feature zu verlassen und closesocket zu verwenden, um sowohl die Abschaltungssequenz zu initiieren als auch die Zuordnung des Sockethandle zu heben.
Um diese Verwendung zu vereinfachen, stellt die Sockets-Schnittstelle Steuerelemente über den Socketoptionsmechanismus bereit, mit denen der Programmierer angeben kann, ob die implizite Herunterfahrsequenz ordnungsgemäß oder abortiv sein soll, und ob die Closesocket-Funktion (die nicht sofort abgeschlossen wird) anhalten soll, um eine ordnungsgemäße Beendigungssequenz zu ermöglichen. Diese wichtigen Unterschiede und die Auswirkungen der Verwendung von Closesocket auf diese Weise sind immer noch nicht weit verbreitet.
Indem Sie geeignete Werte für die Socketoptionen SO _ LINGER und SO _ DONTLINGER festlegen, können die folgenden Verhaltenstypen mit der closesocket-Funktion abgerufen werden:
- Sequenz zum Abbrechen des Herunterfahrens, sofortige Rückgabe von closesocket.
- Ordnungsgemäßes Herunterfahren, verzögerte Rückgabe, bis entweder die Sequenz zum Herunterfahren abgeschlossen ist oder ein angegebenes Zeitintervall verstrichen ist. Wenn das Zeitintervall abläuft, bevor die Sequenz zum ordnungsgemäßen Herunterfahren abgeschlossen ist, tritt eine abortive Shutdown-Sequenz auf, und closesocket wird zurückgegeben.
- Ordnungsgemäßes Herunterfahren, sofortige Rückgabe, sodass die Sequenz zum Herunterfahren im Hintergrund abgeschlossen werden kann. Obwohl dies das Standardverhalten ist, kann die Anwendung nicht wissen, wann (oder ob) die Sequenz des ordnungsgemäßen Herunterfahrens tatsächlich abgeschlossen wird.
Die Verwendung der _ So LINGER- und SO _ DONTLINGER-Socketoptionen und der zugehörigen Lingerstruktur wird in den Referenzabschnitten zu SOL SOCKET Socket _ Options und der linger-Struktur ausführlicher erläutert.
Eine Technik, die verwendet werden kann, um die Wahrscheinlichkeit von Problemen beim Beenden der Verbindung zu minimieren, besteht darin, zu vermeiden, dass ein implizites Herunterfahren durch closesocketinitiiert wird. Verwenden Sie stattdessen eine der beiden expliziten Funktionen zum Herunterfahren, shutdown oder WSASendDisconnect. Dies führt wiederum dazu, dass eine FD _ CLOSE-Angabe von der Peeranwendung empfangen wird, die angibt, dass alle ausstehenden Daten empfangen wurden. Um dies zu veranschaulichen, zeigt die folgende Tabelle die Funktionen, die von den Client- und Serverkomponenten einer Anwendung aufgerufen werden, wobei der Client für das Initiieren eines ordnungsgemäßen Herunterfahrens verantwortlich ist.
| Clientseitig | Serverseitig |
|---|---|
| (1) Ruft das Herunterfahren(s, SD _ SEND) auf, um das Ende der Sitzung zu signalisieren, und dieser Client verfügt nicht mehr über zu sendende Daten. | |
| (2) Empfängt FD _ CLOSE und gibt an, dass das ordnungsgemäße Herunterfahren ausgeführt wird und alle Daten empfangen wurden. | |
| (3) Sendet alle verbleibenden Antwortdaten. | |
| (Nur bedeutung des lokalen Zeitsteuerungsablaufs) Ruft FD READ ab _ und ruft recv auf, um alle vom Server gesendeten Antwortdaten abzurufen. | (4) Ruft das Herunterfahren(s, SD _ SEND) auf, um anzugeben, dass der Server keine daten mehr senden muss. |
| (5) Empfängt die _ FD CLOSE-Angabe. | (Nur bedeutung des lokalen Zeitsteuerungsablaufs) Ruft closesocket auf. |
| (6) Ruft closesocketauf. |