异步循环中的套接字似乎没有返回任何内容

时间:2017-06-07 19:40:29

标签: python python-asyncio

我想更好地了解python中的asyncio,所以决定只使用基本实用程序(如socket和asyncio)编写一个简单的http代理服务器。 这是我的代码

import asyncio
import socket

BUFFER = 4096


class ProxyServer:
    def __init__(self):
        self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.bind(("192.168.1.6", 80))
        self.listener.listen()

    async def invoke(self, loop):
        try:
            while 1:
                conn, addr = self.listener.accept()
                await self.process_new_conn(conn, loop)
        except KeyboardInterrupt:
            loop.stop()
            print("Finishing...")

    async def process_new_conn(self, conn, loop):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sender:
            data = await loop.sock_recv(conn, BUFFER)

            await loop.sock_connect(sender, (host, port))
            sender.send(data)

            response = await loop.sock_recv(sender, BUFFER)
            conn.send(response)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    try:
        ps = ProxyServer()
        loop.run_until_complete(ps.invoke(loop))
    except OSError:
        print("80 port is being used.")
    finally:
        loop.close()

据我了解,loop.run_until_complete将我的coro添加到循环队列并在某些时候执行它。当我调用await self.process_new_conn(conn, loop)循环时,将此coro添加到其队列中。我的问题是如何将队列放入循环中?我的意思是它看起来像process_new_conn中的代码被执行但是另一个套接字什么都没有收到,但是当我尝试键入类似这样的loop.run_until_complete(self.process_new_conn(conn, loop))时,它可以工作(运行时错误但仍然存在)。看起来应该有另一种方法,但我无法找到它。

UPD:我希望,我的测试是错误的。这就是全部。但是在这里我改变了代码并附有一个小解释,以防有人需要。

import asyncio
import socket

from select import select

BUFFER = 4096


class ProxyServer:
    def __init__(self):
        self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.bind(("localhost", 80))
        self.listener.listen()

        self.loop = asyncio.get_event_loop()

    def invoke(self):
        try:
            self.loop.run_until_complete(self.accept_connection())
        except KeyboardInterrupt:
            self.loop.stop()
            self.loop.close()
            print("Finishing...")

    async def accept_connection(self):
        while 1:
            read, _, _ = select([self.listener], [], [], 0.1)
            if read:
                conn, addr = self.listener.accept()
                await self.process_new_conn(conn)

    async def process_new_conn(self, conn):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sender:
            data = await self.loop.sock_recv(conn, BUFFER)
            await self.loop.sock_connect(sender, (host, port))
            sender.send(data)

            response = await self.loop.sock_recv(sender, BUFFER)
            await self.loop.sock_sendall(conn, response)

if __name__ == "__main__":
    try:
        ps = ProxyServer()
        ps.invoke()
    except OSError:
        print("80 port is being used.")

据我所知:使用await我们说一个循环,coro应该被放入一个队列并且可能被中断(这让一个循环在wordd await处切换当前coro)。这段视频给了我很多帮助https://www.youtube.com/watch?v=m28fiN9y_r8&t=679s

0 个答案:

没有答案