sockets - asyncore.dispatcher in python: when are the handle_closed and handle_read executed? -
there 2 files: server.py , client.py, both written of asyncore.dispatcher
server.py
import asyncore, socket class server(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.af_inet, socket.sock_stream) self.bind(('', port)) self.listen(1) print "waiting connection..." def handle_accept(self): socket, address = self.accept() print 'connection by', address socket.send("hello server") def handle_read(self): print "reading..." out_buffer = self.recv(1024) if not out_buffer: self.close() print out_buffer def handle_closed(self): print "server: connection closed" self.close() s = server('0.0.0.0', 5007) asyncore.loop() client.py
import asyncore, socket class client(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.af_inet, socket.sock_stream) self.connect((host, port)) print "client start..." def handle_close(self): print "client: connection closed" self.close() def handle_read(self): data = self.recv(1024) if data: print "received ", data self.send("hello client") c = client('127.0.0.1', 5007) asyncore.loop() result:
execute server.py:
waiting connection... then client.py:
client start... received hello server client: connection closed client: connection closed finally client.py exited, , there 1 more line displayed in ouput window of server.py , server keeps running:
connection ('127.0.0.1', 58197) there cannot understand:
why function
handle_closedin client.py executed twice?why isn't function
handle_readingin server.py executed? client.py has sent message("hello client"), why cannot server receive it?why isn't function
handle_closedin server.py executed? want execute codes in server.py when client exits, seems nothinghandle_closedin server.py?
asyncore talk
the handle_read() in server.py never called.
but why?! it's server class...
yes, server class uses socket listening non-established connections. reads on go handle_accept(), actual channel sockets (connected endpoint) should given new instance of dispatcher-inherited class (preferably). in server's handle_accept() method sockets got accept() local , deleted upon exiting function, so: new connection accepted, text sent , after socket killed.
have read on asyncore module , my answer in other question.
server
you need to, said, make new class connections in server.py:
class clienthandler(asyncore.dispatcher): def handle_read(self): data = self.recv(1024) if not data: return print "received:", data def handle_close(self): print "server: connection closed" self.close() note here reading don't need manually close socket when null recieved - asyncore takes care of closing connection.
then have instantiate in server when connection made:
def handle_accept(self): ... clienthandler(socket) you made spelling mistake in server - method's proper name handle_close. though wouldn't useful. client-connection related in clienthandler.
client
in client.py need modify handle_read():
if data: print "received ", data change to:
if not data: return print "received ", data why? without send() called when socket closed, resulting in handle_close() being called second time, asyncore. said - asyncore takes care of this.
notes
now can write more complex server-side class connections. learn how os-level sockets work, won't trouble.
asyncore pretty nice wrapper sockets, if want higher-lever things, http or smtp processing in event-driven environment, twisted library interest you!
Comments
Post a Comment