Предотвращение конкатенации сообщений с помощью асинхронных сокетов - PullRequest
0 голосов
/ 11 июня 2018

Я использую стандартную клиентскую панель asyncio сокета ниже:

import asyncio

async def repetitive_client_request(message, loop):
    reader, writer = await asyncio.open_connection('127.0.0.1', 8888, loop=loop)
    while True:
        await asyncio.sleep(1)
        writer.write(message.encode())
        await writer.drain()

        data = await reader.read(100)
        print('Received: {}'.format(data.decode()))

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

message = 'hi'
loop = asyncio.get_event_loop()
loop.run_until_complete(repetitive_client_request(message, loop))
loop.close()

97% времени все работает нормально, но иногда последовательные запросы объединяются, например, 'hihihihi'.Кто-то предположил, что такое поведение не является чем-то необычным в TCP.Как я могу изменить вышеупомянутое на UDP, и должно ли это решить проблему?

Редактировать: Только что нашел это в документах: Changed in version 3.6: The socket option TCP_NODELAY is now set by default. Таким образом, похоже, что не Nagle отвечает за объединение этого сообщения.

1 Ответ

0 голосов
/ 11 июня 2018

Кто-то предположил, что такое поведение не является чем-то необычным в TCP.Как я могу изменить вышеупомянутое на UDP

Перед переключением всего кода на UDP, есть другая опция - вы можете сделать свой протокол саморазграничивающим, чтобы отдельные сообщения не могли быть объединены нижележащимтранспорт.

Например, вы можете отправить свои данные, используя:

writer.write(struct.pack('<L', len(data)))
writer.write(data)

При чтении используйте:

size, = struct.unpack('<L', await reader.readexactly(4))
data = await reader.readexactly(size)

Это просто реализовать, сохраняет комфортработы с TCP и предотвращает конкатенацию.

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