2017-02-27 8 views
1

Ich habe eine Client/Server-Anwendung, und es ist sehr einfach. Der Client sendet dem Server eine Nachricht mit Informationen, die einen Dateinamen enthalten. Der Server erstellt diese Datei dann im Serververzeichnis. Der Client sendet dann alle Binärdaten aus der vom Client ausgewählten Datei an den Server (und den Server) schreibt es in die neu gebildete Datei). Der Server muss diese Datei dann ausführen und die gesamte Ausgabe zurück an den Client senden. Es hat gut funktioniert, bis ich diese Sackgasse erreicht habe und es immer weiterläuft. Hier ist eine vereinfachte Version des Codes auf dem Server:Python - Sockets verhalten sich seltsam?

if data_received.startswith("COMMAND:run_file"): #client tells server to create new file 
    #create file 
    while True: 
     #Get binary data from client 
     #If data is blank break 
     #Write data to new file 
    #Close file 
    #Open up new file using subprocess 
    p = Popen("python " + data[17:], shell=True,stdin=PIPE,stdout=PIPE,stderr=STDOUT) 
    print p.stdout.read() #Print output 

Nun, wenn dieser Code ausgeführt wird, erhält der Server die binären Daten der Datei Fein des Kunden, aber dann wird es einfach nur da sitzt ... warten etwas, und es wartet nicht auf einen neuen Befehl vom Client (ich weiß so viel). Ich bin verwirrt, also könnte jemand den (möglicherweise) sehr offensichtlichen Fehler entdecken, den ich irgendwo gemacht habe?

Edit:
ich gefunden habe, wo sie stecken zu bleiben, und es ist nach

print p.stdout.read() 

Jetzt habe ich keine Ahnung, warum dies steckt immer.

+1

Welchen Befehl verwenden Sie, um Binärdaten vom Client abzurufen? – Maaaaa

+0

Der Client sendet Daten 's.sendall (Daten)' und der Server empfängt Daten mit 'conn.recv (1024)' –

+1

Ich schlage vor, dass Sie "data_recieved" verfolgen. Es ist möglich, dass die binären Daten nicht die Länge haben, die Sie denken. Sind Sie Python 2 oder Python 3? Es könnte aufgrund des Unterschieds zwischen Byte- und String-Objekten von Bedeutung sein. (Auch, aber wahrscheinlich nicht verwandt, warum verwenden Sie eine Shell?) – cdarke

Antwort

-1

Wenn Sie conn.recv (1024) verwenden, wird gewartet, bis Daten empfangen werden. Und da Sie sich in einer echten Schleife befinden, wird es kontinuierlich versuchen, Daten zu empfangen, wenn alle Daten gesendet werden, erhält es nichts (anstelle von "leeren Daten"). Daher ist Ihre 'Wenn Daten leer' nie wahr.

+0

Ok danke. Wie kommt es, dass der Client 's.recv (1024)' nicht dasselbe tut? –

+0

Es wartet auch auf die Daten, was denkst du, was es anders macht – Maaaaa

+0

mit dieser Antwort verwechselt: Wo kommt 'conn.recv (1024)' in das Code-Snippet aus der Frage? oder 's.recv (1024)'? – mguijarr

0

Wie in meinem Kommentar gesagt, wenn der Subprozess, den Sie starten, Python ist, würde ich empfehlen, das Modul multiprocessing zu verwenden.

Allerdings, um Ihre Frage zu beantworten, denke ich, stdout ist gepuffert, und stdout.read() wird nur zurückkehren, wenn der Unterprozess endet.

Die Lösung wäre stdout.readline() anstelle von stdout.read() zu verwenden. Auch nicht umleiten stderr zu PIPE, wenn Sie nicht lesen stderr.