Bidrectional Subprocess Communication

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sat Dec 13 23:48:39 EST 2008


En Sat, 13 Dec 2008 18:19:29 -0200, Emanuele D'Arrigo <manu3d at gmail.com>  
escribió:

> I'm trying to replicate the positive results of the Client/Server
> scripts from the thread "Bidirectional Networking", but this time
> using a Process/SubProcess architecture.
>
> The SubProcess, acting as a server, is working just fine. But the
> Process executing the SubProcess, the client, somehow doesn't hear any
> of the standard output from the SubProcess. What am I missing?

(Pipes don't work the same as sockets, although unix-like systems try hard  
to hide the differences...)

- you have to close server.stdin when you don't have more data to send.  
The server will see an end-of-file and knows it has to exit the loop. Same  
thing on the client side.

- you have to wait until the server answers, else it will get a "broken  
pipe" error or similar.

- end-of-file, in Python, is detected when a read/readline returns an  
empty string

- you sent "Stop!" without a \n - readline() on the server side would wait  
forever; it doesn't matter in the code below because server.stdin is  
explicitely closed.

Below are the modified version of your programs:

#clientTest.py

import sys
import threading
 from time import sleep
 from subprocess import Popen, PIPE

## Server Thread
class ListenerThread(threading.Thread):

     def __init__(self, inChannel):
         threading.Thread.__init__(self)
         self.inChannel = inChannel

     def run(self):
         while True:
             data = self.inChannel.readline()
             if not data:  # data=='' means eof
                 break
             data = data.strip()
             print("serverTest.py says: " + data)

print("Starting Client!")

server = Popen("python serverTest.py", stdin=PIPE, stdout=PIPE)

listenerThread = ListenerThread(server.stdout)
listenerThread.start()

server.stdin.write("Something very meaningful!\n")
server.stdin.write("Stop!")
server.stdin.close() # notify server: no more data
listenerThread.join() # wait until server closes channel
print("Client Stopped!")

# serverTest.py
import sys

print("Starting Server!")

while True:
     data = sys.stdin.readline()
     if not data: # data=='' means eof
       break

     data = data.strip()
     print("SERVER RECV: '" + data + "'")

     if(data == "Stop!"):
         break

print("Server Stopped!")


-- 
Gabriel Genellina




More information about the Python-list mailing list