如何使用asyncio UDP客户端添加超时



我的代码是这样的,它基本上只是复制了Python中UDP Echo Client的示例代码
官方文档。

import asyncio
from asyncio import DatagramProtocol

class EchoClientProtocol(DatagramProtocol):
def __init__(self, message, on_con_lost):
self.message = message
self.on_con_lost = on_con_lost
self.transport = None
def connection_made(self, transport):
self.transport = transport
print('Send:', self.message)
self.transport.sendto(self.message.encode())
def datagram_received(self, data, addr):
print("Received:", data.decode())
print("Close the socket")
self.transport.close()
def error_received(self, exc):
print('Error received:', exc)
def connection_lost(self, exc):
print("Connection closed")
self.on_con_lost.set_result(True)

async def main():
loop = asyncio.get_running_loop()
on_con_lost = loop.create_future()
message = "Hello World!"
transport, protocol = await loop.create_datagram_endpoint(
lambda: EchoClientProtocol(message, on_con_lost),
remote_addr=('127.0.0.1', 20001)
)
try:
await on_con_lost
finally:
transport.close()

asyncio.run(main())

效果很好。但是当服务不可用时,客户端将被阻塞。我试着添加asyncio。等待修复,但不工作

transport, protocol = await asyncio.wait_for(loop.create_datagram_endpoint(
lambda: EchoClientProtocol(message, on_con_lost),
remote_addr=('127.0.0.1', 20001)
), 5)

我猜可能是因为我不完全理解on_con_lost的这种用法参数,怎么做?

我认为是这样的:

您正在启动数据报端点。然后在断开连接的未来上有启动器块。要触发断开连接的未来,必须调用connection_lost函数。但是如果一开始就没有连接,connection_made没有被调用,那么未来就不会准备好。你真正想要的是在等待未来的过程中加上超时。如果您得到一个超时过期的异常,然后关闭连接。当前代码的工作方式是,您启动端点,一旦超时,代码将继续等待断开连接,而现在无法准备好。

最新更新