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_closed
in client.py executed twice?why isn't function
handle_reading
in server.py executed? client.py has sent message("hello client"), why cannot server receive it?why isn't function
handle_closed
in server.py executed? want execute codes in server.py when client exits, seems nothinghandle_closed
in 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