Wie man ein hintergrund Verfahren ständig überprüfen, während für die Eingangs - threading?
Habe ich kleine server und-client Python-Skripte, in denen der client sendet einen string, und der server antwortet mit der Rückseite. Wenn der Kunde einen quit-string, der client beendet und dann den server verlässt.
Ich möchte den server "erhalten, rückwärts senden" - Prozedur im hintergrund laufen, während das Programm ständig überprüfen, stdin für einen quit-string.
Ich habe versucht, mit threading
aber wegen der Sperrung, dass viele socket-Aufrufe verursachen, es würde nicht richtig funktionieren.
Nur so können Sie sich eine Vorstellung von dem, was ich bereits getan habe.
server.py:
import socket
from time import sleep
sock = socket.socket()
sock.bind(("127.0.0.1",12346))
sock.listen(3)
print "Waiting on connection"
conn = sock.accept()
print "Client connected"
while True:
m = conn[0].recv(4096)
if m == "exit":
sleep(1)
break
else:
conn[0].send(m[::-1])
sock.shutdown(socket.SHUT_RDWR)
sock.close()
client.py:
import socket
sock = socket.socket()
sock.connect(("127.0.0.1",12346))
while True:
s = raw_input("message: ")
sock.send(s)
if s == "exit":
print "Quitting"
break
print sock.recv(4096)
sock.shutdown(socket.SHUT_RDWR)
sock.close()
- "erhalten, reverse, senden Sie" sieht aus wie die einer sehr kurzen Zeit, meiner Meinung nach, warum Sie möchten, um es im hintergrund laufen lassen?
- Denn ich kann nicht sehen, eine Möglichkeit zu haben, "erhalten, reverse, senden" und "get user input", den gleichen Prozess, weil
raw_input()
blockiert, bis er eine Eingabe erhält, die unterbricht den Fluss der Pakete. Ich habe zwei Ideen, die ich nicht wollen, in die Tat umzusetzen: Geben Sie dem Klienten die Fähigkeit zu töten und die server, oder limit, wie langeraw_input()
Blöcke für (timeout) - Ich verstehe es nicht. Also, was Sie wollen, ist zu kombinieren die zwei scripts "server.py" und "client.py" in einem einzigen Skript und führen Sie einfach, dass ein Skript? Oder wollen Sie einfach nur zu laufen "server.py" im hintergrund (in Unix ist es getan werden kann, mit
python server.py &
)? - Ich will, dass die server in der Lage sein zu senden und zu empfangen Pakete, während gleichzeitig die überprüfung der Benutzereingaben
- Warum möchtest du das tun? Wenn es nur einen client, der client wartet auf den server zurück das Ergebnis sowieso und wird nicht senden Sie keine weiteren Eingaben zu server, richtig? Wahrscheinlich Sie wollen, dass der server in der Lage sein, um mehrere clients statt?
- Sie wollen, dass der server beendet werden, wenn die person, auf die server-Konsole-Typen 'quit' auf stdin? Und diese ist getrennt von der 'exit' den client senden kann? Und Sie wollen, dass der server zum abrufen von Daten auf der Standardeingabe, statt der Sperrung in einem anderen thread?
- Ja. In meinem ideal-design der client nicht in der Lage, senden Sie eine exit-signal an den server; die einzige Möglichkeit zum beenden der server ist von seinem eigenen terminal-Instanz. Während es bei der überprüfung stdin für das quit-signal, ich möchte in der Lage sein, um reibungslos in die Bearbeitung von client-verbindungen, Verbindungstrennungen und die Paketverarbeitung. Kommst du mich?
- Ich denke so, aber ich habe noch zwei weitere klärende Fragen: haben Sie etwas auf stdin anderen als den quit-Befehl und muss es sein, stdin oder kann es ein signal, wie ^C mit einem anmutigen exit?
- Letztendlich möchte ich mehrere server-seitigen Befehle andere als beendet, aber für jetzt, ich brauche keine.
- Ich sehe, ich habe nicht bemerkt, dass von "stdin" es soll bedeuten, dass die "stdin" von dem server-terminal. Ich korrigiere meine Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da Sie möchten, dass der server-Prozess mit dem client, während in der gleichen Zeit, die input von der server
stdin
, können Sie nur die gesamte aktuelle server-code in eineThread
, dann wartet input vonstdin
.und Sie können entfernen Sie die "exit" - Check-in client.
In diesem code, den der server tut nichts, nachdem der client die Verbindung trennen, obwohl, es wird gerade warten Sie, bis "exit" eingegeben werden die
stdin
. Möchten Sie vielleicht erweitern Sie den code, um die server in der Lage zu akzeptieren, neue Kunden, da Sie nicht möchten, dass der client die Möglichkeit haben, schließen Sie den server. In diesem Fall können Sie eine weiterewhile
Schleife ausconn = sock.accept()
zusock.close()
.Und wie @usmcs vorgeschlagen, wenn Sie nicht haben, andere Befehle werden an den server gesendet, es wird besser sein, wenn Sie mit STRG-C (
KeyboardInterrupt
) statt, so brauchen Sie nicht den Faden, während es noch Ende der server ordnungsgemäß (d.h. keine Fehler durch die Tastenkombination STRG-C gemeldet) mit diesem code:Dies ist ein Beispiel für nicht-blockierende socket empfangen. Im Falle von no-Daten zu empfangen, die Buchse, wird eine Ausnahme ausgelöst.
Hier ist ein Beispiel für nicht-blockierende stdin Lesen:
Im Grunde wollen Sie, Sie zu kombinieren und vielleicht fügen Sie einige timeout zu zwingen, das Lesen von stdin, auf einer regelmäßigen basis bei vielen verbindungen.
Nahm ich einen Kern hatte ich bereits veröffentlicht, für den Aufbau einer pre-Gabel-JSON-RPC-Server in Python und verändert den code um dieses problem zu lösen. Kernaussage Hier: https://gist.github.com/matthewstory/4547282
Suchen mehr in warum das funktioniert. Die wichtigsten Gabel laicht
N
viele Gabeln (im Beispiel oben5
), von denen jede geht in einen accept-Schleife:Diese Kind Gabeln kümmert sich um alle eingehenden Anfragen zu
localhost:9999
. Die wichtigsten Gabel fällt dann in ein select/waitpid combo-Schleife:Den
select
wird entweder darauf hindeuten, dassstdin
ist bereit zum Lesen, in diesem Fall werden wir Lesen 1 Zeile von stdin, oder es wird timeout nach1s
, in welchem Fall es fallen wird-direkt durch unsere check für alle verlassenen Kinder (mitos.waitpid
mit derWNOHANG
flag).