Quoth Brad Tilley <br********@usa.net>:
| I have a function that starts a socket server looping continuously
| listening for connections. It works. Clients can connect to it and send
| data.
|
| The problem is this: I want to get the data that the clients send out of
| the loop but at the same time keep the loop going so it can continue
| listening for connections. If I return, I exit the function and the loop
| stops. How might I handle this?
|
| def listen(ip_param, port_param):
| s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
| while 1:
| print "\nWaiting for new connection...\n"
| s.listen(1)
| conn, addr = s.accept()
| print "Client", addr[0], "connected and was directed to port", addr[1]
| data = conn.recv(1024)
| # I want to get 'data' out of the loop, but keep the loop going
| print "Client sent this message:", data
| conn.close()
Well, some people would address this problem by spawning a thread
(and then they'd have two problems! as the saying goes.)
It depends on what you want. Your main options:
- store whatever state you need to resume, and come back
and accept a new connection when you're done with the data -
class SocketConnection:
def __init__(self, ip_param, port_param):
...
def recv(self):
... accept
... recv
... close
return data
- turn it upside down, call the processing function
def listen(ip_param, port_param, data_function):
...
data = conn.recv(1024)
data = data_function(data)
if data:
conn.send(data)
conn.close()
...
- fork a new process (UNIX oriented.)
...
pid = os.fork()
if pid:
wait_for_these_pids_eventually.append(pid)
else:
try:
conn, addr = s.accept()
s.close()
conn_function(conn)
finally:
os._exit(0)
- spawn a new thread (similar idea)
Processes and threads will allow your service to remain responsive
while performing tasks that take a long time, because these tasks
will run concurrently. They do bring their own issues, though, and
it isn't worth it unless it's worth it, which only you can tell.
It's a pretty lengthy computation that takes so much time that a
thread or process is really called for.
If the inverted, functional approach suits your application, note
that you can use a Python class instance here to keep state between
connections - like,
class ConnectionReceiver:
...
def data_function(self, data):
self.count = self.count + 1
print >> sys.stderr, 'datum', self.count
...
...
receiver = ConnectionReceiver()
listen(ip_param, port_param, receiver.data_function)
Donn Cave,
do**@drizzle.com