You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

asyncio.StreamWriter暂停无法发送请求,如何解决?

问题分析与修复方案

问题原因

从你提供的StreamWriter状态能明确看出:

  • 循环后StreamReader标记为paused,且缓存了173203字节未处理数据
  • 核心原因是TCP连接的接收缓冲区被未读取的数据填满,触发了asyncio的流暂停机制。当StreamReader的缓冲区达到高水位线时,会自动暂停读取操作;同时TCP滑动窗口会因接收端未处理数据而收缩,最终导致发送端无法继续写入数据。

修复步骤

你需要在发送数据的同时,持续读取并处理(或直接丢弃)接收端的数据,避免缓冲区被填满。具体实现如下:

1. 编写后台读取协程

创建独立协程持续读取StreamReader的数据,哪怕不需要这些数据,也要清空缓冲区:

async def drain_reader(reader):
    try:
        while True:
            # 按固定大小读取数据,可根据实际场景调整
            data = await reader.read(4096)
            if not data:
                # 读取到空数据,说明连接已关闭
                break
            # 若无需使用数据,此处直接跳过;有业务需求则添加处理逻辑
    except Exception as e:
        # 处理连接异常,比如断开、超时等
        print(f"读取异常: {e}")

2. 并发执行发送与读取逻辑

在启动发送循环前,通过asyncio.create_task启动后台读取任务,确保发送和读取操作同时进行:

# 假设已通过asyncio.open_connection或类似方法获取到reader和writer
async def main():
    reader, writer = await asyncio.open_connection('your_host', your_port)
    
    # 启动后台读取任务,持续清空接收缓冲区
    asyncio.create_task(drain_reader(reader))
    
    request_screen = True
    while request_screen:
        writer.write(b'screenshare')
        await writer.drain()
        # 添加适当延迟,避免高频发送导致网络压力
        await asyncio.sleep(0.05)
    
    # 关闭连接并释放资源
    writer.close()
    await writer.wait_closed()

asyncio.run(main())

额外注意事项

  • 处理连接关闭:当reader.read()返回空字节时,说明对方已关闭连接,此时应终止发送循环并清理资源。
  • 调整读取块大小:4096是常规缓冲区大小,可根据业务场景调整为更合适的值。
  • 控制发送频率:无延迟循环发送可能导致网络拥堵,通过asyncio.sleep()合理控制发送间隔。

内容的提问来源于stack exchange,提问作者Data Reset

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:03:24