Ordnungsgemäßes Herunterfahren, Verweilen und Schließen des Sockets

Das folgende Material wird zur Erläuterung des Themas 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 Protokollnachrichten zwischen den beiden Endpunkten, im Folgenden als Herunterfahren-Sequenz bezeichnet. Es werden zwei allgemeine Klassen von Herunterfahrsequenzen definiert: graceful und abortive (auch als hart bezeichnet). In einer ordnungsgemäßen Herunterfahrsequenz 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 gehen alle nicht gesendeten Daten verloren. Das Auftreten einer Herunterfahrsequenz (ordnungsgemäß oder abgebrochen) kann auch verwendet werden, um den zugehörigen Anwendungen einen FD_CLOSE Hinweis zu geben, dass ein Herunterfahren ausgeführt wird.

Durch das Schließen eines Sockets wird die Zuordnung des Sockethandles aufgehoben, sodass die Anwendung nicht mehr auf den Socket verweisen oder in irgendeiner Weise verwenden kann.

In Windows Sockets können sowohl die Funktion zum Herunterfahren als auch die WSASendDisconnect-Funktion verwendet werden, um eine Herunterfahrsequenz zu initiieren, während die Closesocket-Funktion verwendet wird, um die Zuordnung von Sockethandles aufzugeben und alle zugeordneten Ressourcen freizugeben. Eine gewisse Verwirrung entsteht jedoch aus der Tatsache, dass die Closesocket-Funktion implizit dazu führt, dass eine Herunterfahrsequenz auftritt, wenn sie noch nicht geschehen ist. Tatsächlich ist es zu einer ziemlich gängigen Programmierpraxis geworden, sich auf dieses Feature zu verlassen und closesocket zu verwenden, um sowohl die Herunterfahrsequenz zu initiieren als auch die Zuordnung des Sockethandles zu aufheben.

Um diese Verwendung zu erleichtern, stellt die Sockets-Schnittstelle Steuerelemente über den Socketoptionsmechanismus bereit, mit denen der Programmierer angeben kann, ob die Sequenz des impliziten Herunterfahrens ordnungsgemäß oder abgebrochen werden soll, und ob die Closesocket-Funktion bleiben soll (die nicht sofort abgeschlossen ist), um Zeit für den Abschluss einer ordnungsgemäßen Herunterfahren-Sequenz zuzulassen. Diese wichtigen Unterschiede und die Auswirkungen der Verwendung von Closesocket auf diese Weise sind immer noch nicht weit verbreitet.

Durch Das Festlegen geeigneter Werte für die Socketoptionen SO_LINGER und SO_DONTLINGER können die folgenden Verhaltenstypen mit der closesocket-Funktion abgerufen werden:

  • Sequenz zum abbrechenden Herunterfahren, sofortige Rückgabe aus closesocket.
  • Ordnungsgemäßes Herunterfahren, verzögert die Rückgabe, bis entweder die Herunterfahrsequenz abgeschlossen ist oder ein angegebenes Zeitintervall verstrichen ist. Wenn das Zeitintervall abläuft, bevor die sequenz zum ordnungsgemäßen Herunterfahren abgeschlossen ist, tritt eine Abbruchsequenz zum Herunterfahren auf, und der Closesocket wird zurückgegeben.
  • Ordnungsgemäßes Herunterfahren, sofortige Rückgabe, sodass die Herunterfahrsequenz im Hintergrund abgeschlossen werden kann. Obwohl dies das Standardverhalten ist, kann die Anwendung nicht wissen, wann (oder ob) die ordnungsgemäße Herunterfahrsequenz tatsächlich abgeschlossen wird.

Die Verwendung der SO_LINGER- und SO_DONTLINGER Socketoptionen und der zugehörigen Verweilstruktur wird in den Referenzabschnitten zu SOL_SOCKET Socketoptionen und der linger-Struktur ausführlicher erläutert.

Eine Technik, die verwendet werden kann, um das Risiko von Problemen zu minimieren, die während des Verbindungsabbruchs auftreten, besteht darin, zu vermeiden, dass ein implizites Herunterfahren durch closesocket initiiert wird. Verwenden Sie stattdessen eine der beiden expliziten Herunterfahrfunktionen, shutdown oder WSASendDisconnect. Dies führt wiederum dazu, dass die Peeranwendung einen FD_CLOSE Hinweis empfängt, der 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(en, SD_SEND) auf, um das Ende der Sitzung zu signalisieren, und der Client hat keine weiteren Daten zu senden.
(2) Empfängt FD_CLOSE, die angibt, dass das ordnungsgemäße Herunterfahren ausgeführt wird und dass alle Daten empfangen wurden.
(3) Sendet alle verbleibenden Antwortdaten.
(nur lokale Zeitliche Bedeutung) Ruft FD_READ ab und ruft recv auf, um alle vom Server gesendeten Antwortdaten abzurufen. (4) Ruft das Herunterfahren(en, SD_SEND) auf, um anzugeben, dass der Server über keine weiteren Daten zum Senden verfügt.
(5) Erhält FD_CLOSE Angabe. (nur lokale Zeitliche Bedeutung) Ruft closesocket auf .
(6) Ruft closesocket auf.