I have an IP = '127.0.0.1', port number 'port', and trying
class AClass(asyncore.dispatcher):
def __init__(self, ip, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((ip, port))
def handle_connect(self):
print 'connected'
def handle_read(self):
data = self.recv(8192)
print data
def handle_close(self):
self.close()
Nothing is being printed though.
The sending is being handled by another process. How can I check ? Is the above correct ?
Edit: For sending: a different python program, running separately:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((addr, port))
packet="some string"
sock.sendall(packet+'\r\n')
Nothing happens
If I put, on server side (!!!) print sock.recv(4096)
I see the packet printed - but still nothing happens from the client side.
I assume that you mean for AClass
to be the server-side. In that case, AClass
should not be doing a connect()
. There are two sides to socket communications. On the server-side, you typically create the socket, bind it to an address and port, set the backlog (via listen()
), and accept()
connections. Typically, when you have a new connection from a client, you spawn off some other entity to handle that client.
This code implements an echo server:
import asyncore
import socket
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
self.out_buffer = self.recv(1024)
if not self.out_buffer:
self.close()
print "server:", repr(self.out_buffer)
def handle_close(self):
self.close()
class EchoServer(asyncore.dispatcher):
def __init__(self, ip, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((ip, port))
self.listen(1)
def handle_accept(self):
sock, addr = self.accept()
print "Connection from", addr
EchoHandler(sock)
s = EchoServer('127.0.0.1', 21345)
asyncore.loop()
Notice that in the __init__()
method, I'm binding the socket, and setting the backlog. handle_accept()
is what handles the new incoming connection. In this case, we get the new socket object and address returned from accept()
, and create a new async handler for that connection (we supply the socket to EchoHandler
). EchoHandler
then does the work of reading from the socket, and then puts that data into out_buffer
. asyncore.dispatcher_with_send
will then notice that data is ready to send and write it to the socket behind the scenes for us, which sends it back to the client. So there we have both sides, we've read data from the client, and then turn around and send the same data back to the server.
You can check this implementation in a couple of ways. Here is some python code to open a connection, send a message, read the response, and exit:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((ip, port))
client.sendall("Hello world!\r\n")
print "client:", repr(client.recv(1024))
client.close()
You can also just use telnet as your client using the command telnet localhost 21345
, for this example. Type in a string, hit enter, and the server will send that string back. Here's an example session I did:
:: telnet 127.0.0.1 21345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello!
Hello!
aouaoeu aoeu aoeu
aouaoeu aoeu aoeu
^]
telnet> quit
Connection closed.
In the example, the first "Hello!" is the one I typed in my client, the second one is the echo from the server. Then I tried another string, and it was echoed back as well.
If you've not done socket communications before, I really can't recommend Richard Stevens UNIX Network Programming enough. A 3rd edition is now in print and available on Amazon. It doesn't, however, cover using Python or asyncore. And, unfortunately, asyncore is one module that's really not covered very well in the Python documentation. There some examples out there in the wild that are pretty decent though.
Hopefully, this gets you moving in the right direction.
EDIT: here's a asyncore based client:
class Client(asyncore.dispatcher_with_send):
def __init__(self, ip, port, message):
asyncore.dispatcher_with_send.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((ip, port))
self.out_buffer = message
def handle_connect(self):
print 'connected'
def handle_read(self):
data = self.recv(8192)
print "client:", repr(data)
def handle_close(self):
self.close()