我编写简单的udp客户端程序,但它无法正确接收数据报 .
我的代码如下 .
import asyncio
class EchoClientProtocol:
def __init__(self, message, loop):
self.message = message
self.loop = loop
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())
async def sendChar(transport, msg):
print('send: ', msg)
transport.sendto(msg.encode())
if __name__ == '__main__':
loop = asyncio.get_event_loop()
message = 'Hello World!'
connect = loop.create_datagram_endpoint(
lambda: EchoClientProtocol(message, loop),
remote_addr=('127.0.0.1', 9999)
)
transport, protocol = loop.run_until_complete(connect)
while (True):
try:
ch = input()
except KeyboardInterrupt:
break
loop.run_until_complete(sendChar(transport, ch))
loop.run_forever()
transport.close()
loop.close()
我写了asyncio文件中发布的UDP echo服务器协议程序 .
(https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server-protocol)
运行这些程序,我认为结果是这样的 .
Send: Hello World!
Received: Hello World!
1
send: 1
Received: 1
2
send: 2
Received: 2
但结果就是这样 .
Send: Hello World!
1
send: 1
Received: Hello World!
2
send: 2
Received: 1
结果为什么会改变?
我搜索有关asyncio模块,但我无法解决这个问题 .
1 回答
这是因为
while True
循环在下次发送呼叫之前不会将控制权交还给ioloop -input
正在阻止 . 只需添加一些异步睡眠,ioloop就可以处理接收数据的事件并且因为
input
也将在这里阻止,所以最好将它移动到单独的线程:我已将您的代码与waiting for user input in separate thread混合,当然要重构:)