Aufruf close
und shutdown
haben 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 mehrere Prozesse ein Handle für denselben zugrunde liegenden Socket haben können.
Wenn Sie es aufrufen close
, wird die Anzahl der Handles um eins verringert. Wenn die Anzahl der Handles Null erreicht hat, durchlaufen der Socket und die zugehörige Verbindung den normalen Schließvorgang (effektiv wird ein FIN / EOF an den Peer gesendet), und der Socket wird freigegeben.
Hierbei ist zu beachten, dass die Verbindung nicht geschlossen und der Socket nicht freigegeben wird, wenn die Anzahl der Handles nicht Null erreicht, da ein anderer Prozess noch ein Handle für den Socket hat .
Wenn Sie 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 Handles für den Socket haben. Der Socket wird jedoch nicht freigegeben, und Sie müssen anschließend noch schließen.
shutdown()
mich nie darum gekümmert herauszufinden, was macht :).shutdown()
und in der nächsten Leitung zu sein.close()
? Oder sollte es dazwischen eine Verzögerung geben?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, vom Socket zu lesen oder darauf zu schreiben. Durch Schließen wird der mit dem Socket verknüpfte Speicher freigegeben.
Das Weglassen des Herunterfahrens kann dazu führen, dass der Socket im Betriebssystemstapel verbleibt, bis die Verbindung ordnungsgemäß geschlossen wurde.
IMO sind die Namen "Herunterfahren" und "Schließen" irreführend, "Schließen" und "Zerstören" würden ihre Unterschiede betonen.
quelle
es wird direkt im Socket Programming HOWTO ( py2 / py3 ) erwähnt
quelle
close()
ist ausreichend. Die Python-Dokumentation sollte korrigiert werden.Ist dieser Code oben nicht falsch?
Der Aufruf zum Schließen direkt nach dem Aufruf zum Herunterfahren kann dazu führen, dass der Kernel ohnehin alle ausgehenden Puffer verwirft.
Laut http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable muss man zwischen dem Herunterfahren und dem warten Schließen, bis read 0 zurückgibt.
quelle
Es gibt einige Arten des Herunterfahrens: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx . * nix ist ähnlich.
quelle
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: Wenn Sie Daten von A nach B senden, wird nicht garantiert, dass sie an B gesendet werden, sondern nur an den A os-Puffer, 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 ausgegeben, wenn der Puffer nicht leer ist, dh: Daten wurden noch nicht an den Peer gesendet
Dies ist jedoch irreversibel. Sie können dies tun, nachdem Sie alle Ihre Daten vollständig gesendet haben und sicher sein möchten, dass sie mindestens im Peer-OS-Puffer gespeichert sind
quelle