Asyncore talk
The handle_read()
in server.py will never be called.
But why?! It's a server class...
Yes, but Server
class uses its socket for listening any non-established connections. Any reads on it go to handle_accept()
, where actual channel sockets (connected to some endpoint) should be given to new instance of some dispatcher
-inherited class (preferably). In your Server
's handle_accept()
method sockets got by accept()
were local and thus deleted upon exiting this function, so: new connection was accepted, text was sent and after that socket was immediately killed.
Have some read on asyncore module and my answer in other question.
Server
You need to, like I said, make new class for 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 that reading don't need to manually close socket when null is recieved - asyncore
takes care of properly closing connection.
Then you have to instantiate it in Server
when connection is made:
def handle_accept(self):
...
ClientHandler(socket)
You also made spelling mistake in Server
- method's proper name is handle_close
. Though it wouldn't be useful. Everything client-connection related is in ClientHandler
.
Client
In client.py you just need to modify handle_read()
:
if data:
print "Received ", data
Change to:
if not data:
return
print "Received ", data
Why? Without this send()
would be called even when socket is actually closed, resulting in handle_close()
being called for second time, by asyncore
. Like I said - asyncore
takes care of this.
Notes
Now you can write more complex server-side class for connections. You could also learn how OS-level sockets work, so you won't get into trouble.
asyncore
itself is a pretty nice wrapper for sockets, but if you want to do higher-lever things, like HTTP or SMTP processing in some event-driven environment, then Twisted library would interest you!