Я попытался создать программу, которая соединяет два сокета, записывая данные, считанные с одного сокета, в другой и наоборот.
import socket as sock
import asyncio
BUFF_SIZE = 4096
async def create_relay(s, port, loop):
while True:
s1, _ = await loop.sock_accept(s) # while awaiting sock_accept no other task is run
s2 = sock.socket(sock.AF_INET, sock.SOCK_STREAM)
await loop.sock_connect(s2, ('localhost', port))
loop.create_task(relay(s1, s2, loop))
loop.create_task(relay(s2, s1, loop))
# await asyncio.sleep(1000) # while awaiting sleep the relay tasks are run
async def relay(s1, s2, loop):
data = await loop.sock_recv(s1, BUFF_SIZE)
while data:
await loop.sock_sendall(s2, data)
data = await loop.sock_recv(s1, BUFF_SIZE)
def main():
s = sock.socket(sock.AF_INET, sock.SOCK_STREAM)
s.bind(('localhost', 9999))
s.listen()
loop = asyncio.get_event_loop()
loop.run_until_complete(create_relay(s, 9990, loop))
if __name__ == '__main__':
main()
Пока эта программа успешно устанавливает сокеты, я могу 'на самом деле передавать любые сообщения. Отладка кода показала, что программа застревает на s1, _ = await loop.sock_accept(s)
и не выполняет никакого другого асинхронного кода при await
при другом соединении. Однако, если я добавлю еще await
, например await asyncio.sleep(1000)
в конце цикла create_relay
, реле будет работать хотя бы частично, и я смогу пересылать сообщения в одном направлении.
Может кто-нибудь объяснить, почему этислучаются затворы и как их избежать?