简体   繁体   English

异步未运行handle_connect()

[英]Asyncore not running handle_connect()

from reading the asyncore documentation , it seems handle_connect() should be called after you successfully connect to a listening socket, ie after the TCP handshake is done. 通过阅读asyncore 文档 ,似乎应该在成功连接到侦听套接字之后(即在完成TCP握手之后handle_connect()调用handle_connect() But in practice, it seems asyncore does not run handle_connect() unless it receives or send a packet on the socket. 但在实践中,似乎asyncore不运行handle_connect()除非它收到或插座上发送一个数据包。

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. 然后,我启动一个基于asyncore.dispatcher的客户端,该客户端在创建时会连接到服务器套接字。 The client has a method handle_connect() which sends a "hello" packet to the server. 客户端具有一个handle_connect()方法,该方法将“ hello”数据包发送到服务器。 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. 运行此客户端时,将创建连接,TCP握手成功,并且服务器能够接受该连接,但是没有任何其他反应。 handle_connect() is never called. handle_connect()永远不会被调用。

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. 使asyncore运行handle_connect()的唯一方法是服务器是否通过发送数据包开始,或者是否通过__init()__函数将数据包发送到服务器。 then handle_connect() works and everything works fine. 然后handle_connect()工作正常,一切正常。

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? 还是这只是自编写asyncore以来没有纠正的错误?

Is there any other way to work around this? 还有其他解决方法吗?

Not a workaround for sock.connect but can be used to catch socket.error exception: 不是sock.connect的解决方法,但是可以用来捕获socket.error异常:

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

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. handle_connect可能不会被调用,因为在派生类的init方法中,您可能已使用1调用了setblocking()函数。该连接将在init调用中建立,而handle_connect将永远不会被调用。

if this is not the case, then readable method is returning false and handle_connect doesnt get called. 如果不是这种情况,则可读方法返回false,并且不会调用handle_connect。

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. 我刚刚遇到了与Python 3相同的问题。在某些/全部(现在不记得确切的详细信息)系统上,当建立连接时,会发出“套接字写就绪”事件的信号。 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. 因此,如果在连接套接字之前调度程序的writeable()方法返回False ,则asyncore模块中的select() / poll()函数将永远不会检查套接字是否变为“可写”,并且将永远不会检测到连接建立,并且handle_connect()方法将永远不会被调用。

I fixed it the following way: 我通过以下方式修复它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM