Используя asyncio и Python 3.6, как я могу создать TCP-сервер / клиент, который обрабатывает / отправляет несколько последовательных запросов? - PullRequest
0 голосов
/ 30 сентября 2019

Пример сервера в pydocs выглядит следующим образом:

import asyncio                                                        

@asyncio.coroutine                                                    
def handle_echo(reader, writer):                                      
    data = yield from reader.read(100)                                
    message = data.decode()                                           
    addr = writer.get_extra_info('peername')                          
    print("Received %r from %r" % (message, addr))                    

    print("Send: %r" % message)                                       
    writer.write(data)                                                
    yield from writer.drain()                                         

    print("Close the client socket")                                  
    writer.close()                                                    

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

# Serve requests until Ctrl+C is pressed                              
print('Serving on {}'.format(server.sockets[0].getsockname()))        
try:                                                                  
    loop.run_forever()                                                
except KeyboardInterrupt:                                             
    pass                                                              

# Close the server                                                    
server.close()                                                        
loop.run_until_complete(server.wait_closed())                         
loop.close()                                                          

Я адаптировал пример клиента для выполнения двух последовательных запросов:

import asyncio

async def tcp_echo_client(loop):
    reader, writer = await asyncio.open_connection('127.0.0.1', 8889,
                                                        loop=loop)
    await make_request(reader, writer, "Foo")
    await make_request(reader, writer, "Bar")

    print('Close the socket')
    writer.close()

async def make_request(reader, writer, message):
    print('Send: %r' % message)
    writer.write(message.encode())

    data = await reader.read(100)
    print('Received: %r' % data.decode())

loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(loop))
loop.close()

Наблюдаемое поведение заключается в том, что клиент получает ответ на первый запрос, но сокет закрывается до обработки второго запроса. Таким образом, клиент не получает ответа на второй запрос.

Журналы сервера:

Received 'Foo' from ('127.0.0.1', 58112)
Send: 'Foo'                             
Close the client socket                 

Журналы клиента:

Send: 'Foo'
Received: 'Foo'
Send: 'Bar'
Received: ''
Close the socket

Требуемое поведение для клиента:получить Bar в ответ на второй запрос, оставив сокет открытым между запросами.

Если я закомментирую закрытие сокета на сервере, он блокируется так, что клиент никогда не читает ответ на первый запрос,даже если буфер должен был быть очищен с помощью write.drain().

Навигация была бы наиболее ценной;заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...