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

Python 3.6.5 Asyncio端口阻塞问题:无连接时无法终止进程求助

问题分析与修复方案

我来帮你拆解这个问题:

当没有活跃TCP连接时,按下Ctrl+C进程无响应,核心原因是事件循环的清理流程不完整。具体来说:

  • 无活跃连接时,loop.run_forever()会一直阻塞在监听状态,收到KeyboardInterrupt后,原代码直接执行server.close(),随后调用loop.run_until_complete(server.wait_closed())。但此时事件循环没有被正确终止,导致server.wait_closed()的完成信号无法被事件循环处理,进程会一直卡在这一步。
  • 另外,原handle_echo函数中关闭客户端socket时,只调用了writer.close(),没有等待连接完全关闭(await writer.wait_closed()),这虽然不是当前问题的直接诱因,但会导致连接资源无法及时释放,影响服务器健壮性。

修复后的完整代码

import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    while message != "-":
        addr = writer.get_extra_info('peername')
        print("Received %r from %r" % (message, addr))
        print("Send: %r" % message)
        writer.write(data)
        await writer.drain()
        data = await reader.read(100)
        message = data.decode()
    print("Close the client socket")
    writer.close()
    await writer.wait_closed()  # 等待客户端连接完全关闭

loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, loop=loop)
server = loop.run_until_complete(coro)

print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    print("\nShutting down server...")
    loop.stop()  # 先停止事件循环,确保后续清理任务能被处理

# 关闭服务器并等待所有资源释放
server.close()
loop.run_until_complete(server.wait_closed())
# 清理异步生成器(Python 3.6+ 推荐操作)
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()

关键修复点说明

  1. 添加loop.stop():捕获KeyboardInterrupt后先调用loop.stop(),终止loop.run_forever()的阻塞状态,让事件循环可以切换到处理后续的服务器关闭任务。
  2. 等待客户端连接关闭:在handle_echo中添加await writer.wait_closed(),确保客户端socket完全关闭后再结束协程,避免连接资源泄漏。
  3. 清理异步生成器:调用loop.shutdown_asyncgens(),这是Python 3.6及以上版本的推荐操作,用于清理所有异步生成器,防止潜在的资源泄漏。

修改后,无论是否有活跃连接,按下Ctrl+C都能正常终止进程,完成服务器的优雅关闭。

内容的提问来源于stack exchange,提问作者Jacob Chrzanowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:32:54