Heim  >  Artikel  >  php教程  >  Linux-Netzwerkprogrammierung – der Unterschied zwischen den Funktionen „shut_down“ und „close()“.

Linux-Netzwerkprogrammierung – der Unterschied zwischen den Funktionen „shut_down“ und „close()“.

高洛峰
高洛峰Original
2016-12-13 15:46:071863Durchsuche

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 #include >6 int Shutdown(intsockfd,inthowto)

7 //Rückgabe: 0 – Erfolg, 1 – Fehler

Ja Die Standardaktion eines TCP-Sockets, der close() aufruft, besteht darin, den Socket zu markieren als geschlossen und kehren sofort zum Prozess zurück, der die API aufruft. Zu diesem Zeitpunkt kann der Socket fd aus Sicht der Anwendungsschicht vom Prozess nicht mehr verwendet werden, dh er kann nicht mehr als Parameter zum Lesen oder Schreiben verwendet werden. Aus Sicht der Transportschicht versucht TCP, die aktuell im Sendepuffer angesammelten Daten an die Verbindung zu senden und dann die 4 Wellen von TCP zu initiieren, um die TCP-Verbindung vollständig zu schließen.

Der 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.

SHUT_WR: Schließen Sie die Schreibhälfte entsprechend. Zu diesem Zeitpunkt kann der Kernel keine Daten mehr in den Cache senden werde das wissen. Wenn der Peer versucht zu lesen, kann ein Fehler auftreten.

SHUT_RDWR: Schalten Sie die Lese- und Schreibhälfte aus. Zu diesem Zeitpunkt kann der Benutzer weder vom Socket lesen noch schreiben. Dies entspricht einem erneuten Aufruf der Shutdown-Funktion, wobei SHUT_RD einmal und SHUT_WR einmal angegeben werden.

SHUT_** werden durch Makros in der Funktionsbibliothek definiert. Da Shutdown ein zweites Makro bereitstellt, kann es das Schließen eines Socket-Deskriptors genau steuern, was für die realisierte Close-Funktion nicht möglich ist. In einer Multithread-Umgebung kann ein Deskriptor von mehreren Threads kopiert werden, und der Kernel verwaltet einen Dateireferenzzähler. Close kann den Dateideskriptor nur dann schließen, wenn der Referenzzähler Null ist.

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.

2>. Wenn in einem Multiprozess ein Prozess heruntergefahren wird (sfd, SHUT_RDWR), können andere Prozesse nicht kommunizieren. Wenn ein Prozess geschlossen wird (sfd), hat dies keine Auswirkungen auf andere Prozesse.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Linux-Befehl: HerunterfahrenNächster Artikel:Linux-Befehl: Herunterfahren