In der Linux C-Netzwerkprogrammierung gibt es zwei Methoden, um eine verbundene Netzwerkkommunikation zu schließen. Ihre Funktionsprototypen sind:
1 #unistd.h> 🎜>
2 int close(intsockfd) 3 //Rückgabe: 0 – Erfolg, 1 – Fehler 4 #includeDer Aufruf von close() ist ein normaler Weg, eine TCP-Verbindung zu schließen, es gibt jedoch zwei Einschränkungen auf diese Weise, und das ist der Grund für die Einführung von Shutdown():
1) close() verweist eigentlich nur auf den Socket fd Der Zähler wird um 1 dekrementiert. Erst wenn der Referenzzähler des Sockets fd auf 0 reduziert wird, initiiert die TCP-Transportschicht einen 4-Wege-Handshake, um die Verbindung wirklich zu schließen. Beim Herunterfahren können die zum Schließen der Verbindung erforderlichen 4 Handshakes direkt initiiert werden, ohne durch die Referenzanzahl eingeschränkt zu werden.2) close() beendet die TCP-Duplex-Verbindung. Aufgrund der Vollduplex-Natur der TCP-Verbindung kann es zu einem solchen Anwendungsszenario kommen: Der lokale Peer sendet keine Daten mehr an den Remote-Peer, und der Remote-Peer muss möglicherweise noch Daten senden Der lokale Peer möchte den Remote-Peer darüber informieren, dass er keine Daten mehr sendet, aber weiterhin Daten empfängt. Close () kann nicht verwendet werden, Shutdown () kann diese Aufgabe jedoch ausführen.
Der erste Parameter sowohl der Schließfunktion als auch der Shutdown-Funktion stellt einen Dateideskriptor dar. Wir wissen, dass im Linux-Betriebssystem alles als Datei behandelt wird und alle Dinge, wie Geräte und Speicher, als Dateien simuliert werden. Die Kommunikation zwischen Netzwerken ist natürlich keine Ausnahme. Jeder Kommunikationssitzung ist ein Dateideskriptor zugeordnet, und Ihre Operationen zwischen ihnen ähneln der Bedienung lokaler Dateien. In der Shutdown-Funktion gibt es auch einen Parameter howto, der die folgenden drei Werte hat:
SHUT_RD: Schließen Sie die Lesehälfte. Zu diesem Zeitpunkt kann der Benutzer keine Daten mehr aus diesem Socket lesen Die von diesem Socket empfangenen Daten werden verworfen und der Peer erfährt von diesem Vorgang nichts. Schließen Sie die Leseseite der Verbindung. Das heißt, der Socket akzeptiert keine Daten mehr und alle Daten, die sich derzeit im Empfangspuffer des Sockets befinden, werden verworfen. Der Prozess kann keine Lesevorgänge an den Socket senden. Alle nach diesem Aufruf am TCP-Socket empfangenen Daten werden bestätigt und anschließend stillschweigend verworfen.
Es gibt zwei Einschränkungen bei der Verwendung der Funktion „Schließen“, die jedoch durch die Verwendung von „Shutdown“ vermieden werden können:
Die Funktion „Schließen“ verringert den Referenzzähler des Deskriptors um eins, und erst wenn der Zähler 0 wird, wird der Der Deskriptor ist eine wirklich geschlossene Schnittstelle und die Verwendung der Shutdown-Funktion kann unabhängig vom Referenzzähler die normale Verbindungsbeendigungssequenz auslösen. Da es sich bei der TCP-Verbindung um eine Vollduplex-Verbindung handelt, müssen wir den Peer manchmal darüber informieren, dass wir das Senden von Daten abgeschlossen haben. Wir müssen nur einen Kanal für die Datenübertragung schließen, können aber weiterhin die vom Peer gesendeten Daten empfangen Dies kann über die Shutdown-Funktion erreicht werden.
1>. Wenn sich mehrere Prozesse einen Socket teilen, wird der Zähler bei jedem Aufruf von close um 1 verringert, bis der Zähler 0 erreicht, d. h. alle verwendeten Prozesse haben close und den Socket aufgerufen wird veröffentlicht.