不,你不能期望socket.sendto
是非阻塞的。
相反,使用DatagramTransport.sendto:
将数据字节发送到由 addr(传输-> 依赖目标地址)给定的远程对等方。如果 addr 为 None,则数据将发送到创建传输时给定的目标地址。
该方法不阻塞;它缓冲数据并安排将其异步发送出去。
数据报传输由loop.create_datagram_endpoint协程返回:
transport, protocol = await loop.create_datagram_endpoint(factory, sock=sock)
编辑 - 关于您的评论:
socket.sendto() 是否等同于 transport.sendto()?
不,不是,transport.sendto
用于loop.add_writer
使操作非阻塞。请参阅实施。
我不想使用这种方法,因为它的实现强制我通过具有回调样式的协议接收数据。
较低级别的 asyncio 基于回调,并且 asyncio 不为 UDP 提供基于协程的对象。但是,我编写了一个模块,为 asyncio 提供高级 UDP 端点。
用法:
async def main():
local = await open_local_endpoint()
remote = await open_remote_endpoint(*local.address)
remote.write(b'Hey Hey, My My')
data, addr = await local.read()
message = "Got {data!r} from {addr[0]} port {addr[1]}"
print(message.format(data=data.decode(), addr=addr))
输出:
Got 'Hey Hey, My My' from 127.0.0.1 port 45551