【问题标题】:Python3.8 asyncio Streams and readPython3.8 asyncio Streams 和读取
【发布时间】:2021-01-02 08:12:24
【问题描述】:

这可能是一个愚蠢的问题,但我遗漏了一些我认为可能很明显的东西:

我正在使用 Python 3.8 异步流:

import asyncio

async def client_handler():
    reader, writer = await asyncio.open_connection('127.0.0.1', 9128)

    server_name = writer.get_extra_info('peername')[0]
    print(f"Connecting to: { server_name }")
    data = b''
    close_client = False
    try:
        while not close_client:
            print(data)
            data = await reader.read(1024)
            print(data)
            if data != b'':
                print(data.decode('utf-8'))
                data = b''
        writer.close()
    except:
        pass
    finally:
        writer.close()
        await writer.wait_closed()

asyncio.run(client_handler())

我想我预计它会尝试读取 1024 字节,但如果那里什么都没有,那么它只会返回 None 或空字节字符串或其他东西,但它只是坐在那里直到接收到数据。

我是否误解了 read 应该做什么?是否可以使用另一种方法来查看缓冲区或轮询以查看是否有任何数据实际传入?

例如,假设我正在编写一个示例聊天程序服务器和客户端,它们需要能够同时动态发送和接收数据......我如何使用 asyncio 流实现它?我应该只构建自己的 asyncio.Protocol 子类吗?

【问题讨论】:

    标签: python sockets stream python-asyncio


    【解决方案1】:

    您可以使用asyncio.gather()asyncio.wait(return_when=FIRST_COMPLETED)asyncio.wait_for() 等工具在不同的操作之间进行多路复用,例如从不同的流中读取或读取和写入。如果没有关于您的用例的更多详细信息,很难给您具体的建议如何继续。

    构建asyncio.Protocol 或直接使用feed_eof() 几乎肯定是错误的方法,除非您正在编写非常专业的软件并且确切地知道自己在做什么。

    【讨论】:

    • 对于客户端,我希望只对单个服务器进行读写,而不是从多个服务器/流
    • @DavidTorrey 那么,您还需要什么?为什么await stream.read(n) 实际上在等待新数据对您来说是个问题?
    • 我不应该也需要相同的循环才能写出来吗?如果它只是试图阅读而被锁定,我将如何发送数据?我误解了吗?比如说作为客户端,我希望能够在终端中随机输入并在等待读取数据时将其写入服务器。
    • 或者,例如,我正在等待来自服务器的数据,但我希望能够在等待更多数据的同时将某些内容发送回服务器在...可能是按钮单击或中断等...
    • @DavidTorrey 然后你会有两个并行运行的协程,一个负责从终端读取数据并将其传输到网络,另一个负责从网络读取数据并将数据显示给客户端。 Asyncio 将在同一个线程和同一个事件循环上运行,将它们变成异步代码。这就是我所说的“在答案中使用asyncio.gather() 之类的工具。
    猜你喜欢
    • 2022-11-19
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多