Why does my socket connection between two python scripts break if one of them is launched with Popen? -
so have 2 simple python scripts communicate on socket. right both running on same windows pc.
here's controller.py:
import socket import time import sys subprocess import popen, create_new_console host = '192.168.1.107' # remote host port = 50557 # same port used server s = socket.socket(socket.af_inet, socket.sock_stream) try: s.connect((host, port)) except: popen([sys.executable, 'driver.py'], creationflags=create_new_console) time.sleep(0.2); s.connect((host, port)) s.send(sys.argv[1]) data = s.recv(1024) s.close() print 'received', repr(data)
and here's driver.py:
import socket host = '' # symbolic name meaning local host port = 50557 # arbitrary non-privileged port s = socket.socket(socket.af_inet, socket.sock_stream) s.bind((host, port)) s.listen(1) while 1: print 'waiting controller connection.' conn, addr = s.accept() print 'connected ', addr while 1: data = conn.recv(1024) print 'recieved ', data if not data: break if data == 'q': quit() print 'a.' conn.send(data[::-1]) print 'b.' print 'c.' conn.close()
if open 2 cmd
windows , python <filename>.py <arg>
them both works fine. can leave driver.py
running , run controller.py
on , on again. until kill driver sending "q".
the try/except statement opens new window , runs driver.py
if connection can't made. theoretically makes sure receiver running before sends anything. works reason driver.py
hangs inside second while loop reasons cannot explain. here's output sequential controller.py
calls:
microsoft windows [version 6.1.7601] copyright (c) 2009 microsoft corporation. rights reserved. >python controller.py firstmsg received 'gsmtsrif' >python controller.py secondmsg received 'gsmdnoces' >python controller.py q received '' >python controller.py thirdmsg received 'gsmdriht' >python controller.py fourthmsg
(after fourthmsg controller.py
hangs forever)
here's output driver.py
microsoft windows [version 6.1.7601] copyright (c) 2009 microsoft corporation. rights reserved. >python driver.py waiting controller connection. connected ('192.168.1.107', 49915) recieved firstmsg a. b. recieved c. waiting controller connection. connected ('192.168.1.107', 49916) recieved secondmsg a. b. recieved c. waiting controller connection. connected ('192.168.1.107', 49917) recieved q
(whereupon returns regular command prompt.) new window created popen contains this: waiting controller connection. connected ('192.168.1.107', 49918) recieved thirdmsg a. b.
so in weird new window (which noticed not or act regular cmd window) program seems hang on data = conn.recv(1024)
.
why driver.py
act differently in new window, , how can fix it?
you asked sockets , popen, answer ignore , try propose solution use case, have shown - remote communication on network.
with sockets easy run never ending problems. if have both endpoints under control, zeromq communication turn programming having fun.
you may either use zeromq directly (if check examples pyzmq
, find short , easy while serving in many difficult scenarios), today show use of zerorpc
library, makes remote calls simpler.
install zerorpc
$ pip install zerorpc
write worker.py
def reverse(text): """ return reversed argument """ return text[::-1] def makebig(text): """ turn text uppercase letters """ return text.upper()
call worker methods command line
start server serving worker.py functions
$ zerorpc --server --bind tcp://*:5555 worker binding "tcp://*:5555" serving "worker"
consume services (from command line)
simple call, reporting available functions call
$ zerorpc tcp://localhost:5555 connecting "tcp://localhost:5555" makebig turn text uppercase letters reverse return reversed argument
then call these functions:
$ zerorpc tcp://localhost:5555 reverse "alfabeta" connecting "tcp://localhost:5555" 'atebafla' $ zerorpc tcp://localhost:5555 makebig "alfabeta" connecting "tcp://localhost:5555" 'alfabeta'
note: far have wrote 7 lines of code , able calling remotely.
using python code
command line utility zerorpc
handy utility, free integrate without it, using pure python.
consuming python code client.py
import zerorpc client = zerorpc.client() url = "tcp://localhost:5555" client.connect(url) print client.reverse("alfabeta") print client.makebig("alfabeta")
and run it
$ python client.py atebafla alfabeta
run remote server python code server.py
import zerorpc import worker url = "tcp://*:5555" srv = zerorpc.server(worker) srv.bind(url) srv.run()
stop older server started command zerorpc
, if still runs.
then start out python version of server:
$ python server.py
(it not print anything, waits serve).
finally, consume python code
$ python client.py atebafla alfabeta
conclusions
- using zeromq or zerorpc simplifies situation lot
- play starting client.py , server.py in various orders
- try run multiple clients
- try consume services computer (over network)
- zerorpc provides more patterns (streamer, publish/subscribe), see zerorpc test suite
zerorpc
solves integration task , let focus on coding real functions
Comments
Post a Comment