Python异步套接字recv不起作用

Posted

技术标签:

【中文标题】Python异步套接字recv不起作用【英文标题】:Python async socket recv not working 【发布时间】:2016-06-03 08:15:47 【问题描述】:

这是一个简单的客户端,它连接并发送一条短信:

class Client(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.connect( (host, port) )
        self.buffer = bytes("hello world", 'ascii')

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print(self.recv(8192))

    def writable(self):
        return (len(self.buffer) > 0)

    def writable(self):
        return True

    def handle_write(self):
        sent = self.send(self.buffer)
        print('Sent:', sent)
        self.buffer = self.buffer[sent:]


client = Client('localhost', 8080)
asyncore.loop()

这是必须接收消息并将其回显的服务器:

class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_read(self):
        self.buffer = self.recv(4096)
        while True:
            partial = self.recv(4096)
            print('Partial', partial)
            if not partial:
                break
            self.buffer += partial

    def readable(self):
        return True

    def handle_write(self):
        pass

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        self.handle_read()
        print(self.buffer)


if __name__ == "__main__":
    server = Server("localhost", 8080)
    asyncore.loop()

问题是服务器没有读取任何内容。当我打印 self.buffer 时,输出是:

b''

我做错了什么?

【问题讨论】:

你的服务器代码中的self.accept()在哪里? 我认为异步套接字不需要这样做:docs.python.org/3/library/asyncore.html 我有上一个示例中的这段代码。并且连接被接受,因为 handle_accepted 中的打印语句将其打印出来。 好的,我看到了。我已经阅读了 Py 2 的文档。但它认为,您应该使用单独的类来处理与客户端的连接。如果你一起写,它不可能是异步的。 【参考方案1】:

首先,您需要两个处理程序:一个用于服务器套接字(您期望只有accept),一个用于实际的通信套接字。另外,readhandle_read中只能调用一次;如果你调用它两次,第二次调用可能会阻塞,这在异步编程中是不允许的。不过不用担心;如果您的读取没有得到所有内容,一旦您的读取处理程序返回,您将立即再次收到通知。

import asyncore

class Handler(asyncore.dispatcher):
    def __init__(self, sock):
        self.buffer = b''
        super().__init__(sock)

    def handle_read(self):
        self.buffer += self.recv(4096)
        print('current buffer: %r' % self.buffer)


class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        Handler(sock)


if __name__ == "__main__":
    server = Server("localhost", 1234)
    asyncore.loop()

【讨论】:

以上是关于Python异步套接字recv不起作用的主要内容,如果未能解决你的问题,请参考以下文章

网络上的Python套接字ipv6不起作用

Isend/Irecv 不起作用,但 Send/Recv 可以

SpringBoot异步任务及Async不起作用的原因

Python QtNetwork.QTcpSocket.readAll() 和 QtNetwork.QTcpSocket.write() 不起作用

为啥在注释“cout”时此代码不起作用?

设置套接字流不起作用