it-swarm.com.de

socket.shutdown vs socket.close

Kürzlich habe ich ein bisschen Code gesehen, der so aussah (wobei sock natürlich ein Socket-Objekt ist):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

Was genau ist der Grund, um das Herunterfahren des Sockets und das Schließen des Sockets aufzurufen? Wenn es einen Unterschied macht, wird dieser Socket für nicht blockierende E/A verwendet.

117
Jason Baker

Hier ist eine Erklärung :

Sobald ein Socket nicht mehr benötigt wird, kann das aufrufende Programm den Socket verwerfen, indem eine Close-Subroutine auf den Socket-Deskriptor angewendet wird. Wenn einem zuverlässigen Übermittlungssocket bei einem Abschluss Daten zugeordnet sind, versucht das System weiterhin, Daten zu übertragen. Wenn die Daten jedoch noch nicht zugestellt wurden, werden sie vom System verworfen. Wenn das Anwendungsprogramm keine ausstehenden Daten verwendet, kann es die Shutdown-Subroutine auf dem Socket verwenden, bevor es geschlossen wird.

36
Bob Nadler

Das Aufrufen von close und shutdown hat zwei unterschiedliche Auswirkungen auf den zugrunde liegenden Socket.

Als Erstes muss darauf hingewiesen werden, dass der Socket eine Ressource im zugrunde liegenden Betriebssystem ist und dass mehrere Prozesse ein Handle für denselben zugrunde liegenden Socket haben können.

Wenn Sie close aufrufen, wird die Anzahl der Handles um eins verringert, und wenn die Anzahl der Handles Null erreicht hat, werden der Socket und die zugehörige Verbindung normal geschlossen (wobei effektiv ein FIN/EOF an gesendet wird) der Peer) und der Socket wird freigegeben.

Hier ist zu beachten, dass die Verbindung nicht geschlossen wird und die Zuordnung des Sockets nicht aufgehoben wird, wenn die Anzahl der Handles nicht Null erreicht, da ein anderer Prozess noch ein Handle zum Socket hat.

Wenn Sie dagegen shutdown zum Lesen und Schreiben aufrufen, wird die zugrunde liegende Verbindung geschlossen und ein FIN/EOF an den Peer gesendet, unabhängig davon, wie viele Prozesse über Handles für den Socket verfügen. Allerdings geht nicht hebt die Zuordnung des Sockets auf und Sie müssen danach noch close anrufen.

223

Erklärung zum Herunterfahren und Schließen: Graceful shutdown (msdn)

Das Herunterfahren (in Ihrem Fall) zeigt an, dass am anderen Ende der Verbindung keine weitere Absicht besteht, aus dem Socket zu lesen oder in diesen zu schreiben. Anschließend wird durch Schließen der dem Socket zugeordnete Speicher freigegeben.

Das Weglassen des Herunterfahrens kann dazu führen, dass der Socket im Stapel der Betriebssysteme verweilt, bis die Verbindung ordnungsgemäß geschlossen wurde.

IMO sind die Namen 'shutdown' und 'close' irreführend, 'close' und 'destroy' würden ihre Unterschiede betonen.

18
Dale Reidy

es wird direkt in der Socket-Programmieranleitung erwähnt ( py2 / py )

Verbindung trennen

Genau genommen sollten Sie shutdown für einen Socket verwenden, bevor Sie close damit beginnen. Das shutdown ist eine Empfehlung für den Socket am anderen Ende. Abhängig von dem Argument, das Sie übergeben, kann dies bedeuten: " Ich werde nicht mehr senden, aber ich werde trotzdem zuhören", oder " Ich höre nicht zu, Gute Befreiung ! ”. Die meisten Socket-Bibliotheken werden jedoch von Programmierern verwendet, die diese Etikette vernachlässigen, sodass ein close normalerweise dasselbe wie shutdown(); close() ist. In den meisten Situationen ist ein explizites Herunterfahren nicht erforderlich.

...

7
mykhal

Ist dieser Code oben nicht falsch?

Der Close-Aufruf direkt nach dem Shutdown-Aufruf kann dazu führen, dass der Kernel ohnehin alle ausgehenden Puffer löscht.

Laut http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable braucht man zwischen dem Herunterfahren und dem Schließen warten, bis das Lesen 0 zurückgibt.

5
Christian

es gibt einige Arten des Herunterfahrens: http://msdn.Microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx . * nix ist ähnlich.

4
Ray Tayek

Beim Herunterfahren (1) wird der Socket no gezwungen, weitere Daten zu senden

Dies ist nützlich in

1- Pufferspülung

2- Seltsame Fehlererkennung

3- Sichere Bewachung

Lassen Sie mich näher erläutern, dass beim Senden von Daten von A nach B nicht garantiert wird, dass sie an B gesendet werden. Es wird nur garantiert, dass sie an den A os-Puffer gesendet werden, der sie wiederum an den B os-Puffer sendet

Wenn Sie also shutdown (1) für A aufrufen, leeren Sie den Puffer von A und es wird ein Fehler ausgelöst, wenn der Puffer nicht leer ist, dh: Es wurden noch keine Daten an den Peer gesendet

Dies ist jedoch irreversibel. Sie können dies also tun, nachdem Sie alle Ihre Daten vollständig gesendet haben und sicherstellen möchten, dass sie mindestens im Peer-OS-Puffer gespeichert sind

2
user306166