2017-06-06 2 views
0

Ich habe versucht, ein einfaches Chat-System mit dem Socket-Modul in Python zu machen. Alles funktioniert, außer dass ich den Prozess jedes Mal beenden muss, wenn ich den Server herunterfahren möchte. Und ich möchte das nicht jedes Mal machen. Also meine Frage ist:Python Sockets - Wie man den Server herunterfährt?

Wie kann ich eine Funktion machen, dass, wenn ich Abschaltung im Server-Terminal eingeben, den gesamten Server Abschaltungen?

Ich habe bereits versucht, dies zu tun:

def close(self): server.close(self) server.shutdown(self)

Aber es funktioniert nicht. Wenn ich close() tippe, passiert nichts. Nichts.

Heres der vollständige Code der server.py: https://pastebin.com/gA4QYmQe Jede Hilfe ist nützlich. Vielen Dank.

+0

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

+0

Ich habe den ersten Beitrag bearbeitet. Es sollte den gesamten Server herunterfahren (Schließen Sie das Programm) – smaxxx

+0

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

Antwort

0

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

Verwandte Themen