Asyncore not running handle_connect()

857 views Asked by At

from reading the asyncore documentation, it seems handle_connect() should be called after you successfully connect to a listening socket, i.e after the TCP handshake is done. But in practice, it seems asyncore does not run handle_connect() unless it receives or send a packet on the socket.

As an example:

I have server socket binded and listening on a certain port. The socket will accept any incoming connection, print what it receives, and send "thank you" back.

I then start an asyncore.dispatcher based client, who connects to the server socket when created. The client has a method handle_connect() which sends a "hello" packet to the server. It also has a method read that prints the packet received. (in this case it should print "thank you")

When this client is run, the connection is created, the TCP handshake is successful, and the server is able to accept the connection, but nothing else happens. handle_connect() is never called.

The only way to make asyncore run handle_connect() is if the server start by sending a packet, or if i send a packet to the server in the __init()__ function. then handle_connect() works and everything works fine.

Is this how things are supposed to work? and if so, why? or is this just a bug that no corrected since asyncore was written?

Is there any other way to work around this?

3

There are 3 answers

0
dimcha On

Not a workaround for sock.connect but can be used to catch socket.error exception:

def handle_error(self):
    t, v, tb = sys.exc_info()
    if t == socket.error:
        print("Connect error")
0
Roman Dmitrienko On

I've just ran into the same problem with Python 3. On some/all (can't remember exact details now) systems, when a connection is established, the "socket write ready" event is signalled. Thus, if your dispatcher's writeable() method returns False before the socket is connected, the select()/poll() function in the asyncore module will never check if the socket becomes "writeable", the connection establishment will never be detected, and the handle_connect() method will never be called.

I fixed it the following way:

def writable(self):
    if not self.connected:
        return True
    # ... your logic goes here
0
slaventos On

handle_connect may not be called because in your init method for the derived class you may have called setblocking() function with 1. The connection will be established within init call and handle_connect will never be called.

if this is not the case, then readable method is returning false and handle_connect doesnt get called.