Nun ... es gibt viele Probleme mit dem Code (Ihre „MY IP“ und „SERVERIP“ sind wahrscheinlich nicht, was Sie wollen, aber das ist nebensächlich.
Ihre close() Funktion ein "self" -Parameter, was sinnlos ist, da dies keine Klasse ist. Sie müssen auch die close-Funktion an den Anfang Ihres Codes verschieben, wenn Sie ihn von Ihrer try-excern-Struktur aufrufen möchten. Sie müssen shutdown() aufrufen. und dann close() und shutdown ein Argument. ich habe Ihre close() geändert, dies zu tun und es funktioniert.
def close():
server.shutdown(socket.SHUT_RDWR)
server.close()
print ("closed")
Wenn Sie Ihre Socket öffnen, können Sie auch SO_REUSEADDR setzen sollten machen die Adresse wiederverwendbar (dh Sie erneut den Server starten, wenn das System herunterzufahren, anstatt für eine Minute für TIME_WAIT Zustand des Wartens mit dem Server-Port zu beenden):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Aber wie genau rufen Sie close () wenn Sie irgendwo "shutdown" eingeben? Du machst das nicht. Ihr Programm befindet sich in der Socket-Schleife und liest keine Tastatureingabe.
Ich sehe keinen Sinn, Tastatureingabe zu diesem Programm hinzuzufügen. Erstens erhöht es die Komplexität, da Sie mit zwei möglicherweise blockierenden Eingängen arbeiten (Socket-Eingang und Tastatur-Eingang), und Sie müssten dies verwalten. Es ist möglich, aber auf jeden Fall kompliziert. Zweitens ist es schneller, Strg + C zu drücken, anstatt "shutdown" zu tippen und Enter zu drücken.
Sie rufen derzeit nicht nach einem Tastaturinterrupt auf. Ich habe dies zum inneren KeyboardInterrupt hinzugefügt (das Äußere, das Sie entfernen können - es tut nichts und wird nie erreicht) und es schließt jetzt Ihr Programm ordentlich ab und schließt alle Verbindungen. Denken Sie daran, close() Funktion vom Boden des Codes an die Front vor dem Versuch zu verschieben: Aussage:
except KeyboardInterrupt:
print("[!] Keyboard Interrupted!")
close()
break
Wenn Sie einen Remote Shutdown möchten (Server heruntergefahren, wenn Sie „shutdown“ auf den Socket-Typ), Sie können dies Ihrem Server-Loop hinzufügen:
if message == "shutdown":
close()
exit(0)
Es gibt auch andere Probleme. Wenn Sie beispielsweise Ihren Server starten, eine Verbindung zu ihm herstellen und die Verbindung herunterfahren, wird Ihr Server beendet, da er nicht mehr zu listen() zurückkehrt.
Dies ist auch (meiner Meinung nach) etwas schlechte Programmierung, wie Sie "Server" als globale Variable verwenden.Ich würde eher eine Klasse erstellen und alle Socket-Operationen darin einfügen, aber wenn Stil nicht wichtig ist, sollte dies funktionieren.
Hannu
Könnten Sie bitte Ihren Beitrag ändern, um ein bisschen mehr Code aufzunehmen? Was ist eine "Server" -Instanz in diesem Code-Snippet? Wie ist die Gesamtstruktur Ihres Serverprogramms? Was meinst du mit "Herunterfahren"? Beenden Sie das Programm? Hör auf neue Verbindungen zu hören? Schließen Sie alle bestehenden Verbindungen, lassen Sie aber das Serverprogramm laufen? – Hannu
Ich habe den ersten Beitrag bearbeitet. Es sollte den gesamten Server herunterfahren (Schließen Sie das Programm) – smaxxx
Nur ein weiterer Kommentar, falls Sie interessiert sind. Dies akzeptiert jetzt nur eine gleichzeitige Verbindung und wird nicht gut wiederhergestellt, wenn ein Client die Verbindung herunterfährt. Normalerweise werden diese so ausgeführt, dass das Hauptprogramm in accept() wartet, und wenn eine neue Verbindung hergestellt wird, startet es einen Thread mit Sock und Adresse als Parameter, und der Thread behandelt die einzelne Verbindung, während das Hauptprogramm zu accept() zurückkehrt. sofort. Wenn ein Client die Verbindung schließt, wird der Thread, der ihn bereitstellt, beendet, wobei andere Clientverbindungen und die Hauptschleife intakt bleiben. – Hannu