Парсер для буферов TCP - PullRequest
0 голосов
/ 12 июня 2018

Я хочу реализовать протокол для обмена данными между сервером и клиентом.Я не знаю правильный.Сохраняя производительность в качестве основных критериев, любой может предложить лучший протокол для анализа данных.

Я имею в виду один, не настоящее имя, но он будет похож на этот

[Header][Message][Header][Message]


заголовок содержит длину сообщения, а размер заголовка фиксирован.Я попробовал это с некоторыми, выполнив много операций конкатенации и подстроки, которые стоят дороже.Можно ли предложить лучшую реализацию для этого

Ответы [ 2 ]

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

Для синтаксического анализа существует два распространенных решения:

  1. маленькие сообщения

Получение данных в буфер, например, 64 КБ.Затем используйте указатели в этот буфер для разбора заголовка и сообщения.Поскольку сообщения малы, в буфере может быть много сообщений, и вы будете вызывать анализатор снова, если в буфере есть данные.Обратите внимание, что последнее сообщение в буфере может быть усечено.В этом случае вы должны сохранить частичное сообщение и прочитать больше данных в буфер.Если сообщение ближе к концу буфера, возможно, потребуется скопировать его на передний план.

большие сообщения

Для больших сообщений имеет смысл сначала читать только заголовок.Затем проанализируйте заголовок, чтобы получить размер сообщения, выделите соответствующий буфер для сообщения и затем прочитайте все сообщение в нем, прежде чем анализировать его.

Примечание. В обоих случаях может потребоваться обрабатывать слишком большие сообщения любым изпропустить их или разорвать соединение с ошибкой.В первом случае сообщение не может быть больше буфера и должно быть намного меньше.Во втором случае вы не хотите выделять, например, гигабайт для буферизации сообщения, если предполагается, что они должны занимать всего около 1 МБ.

Для отправки сообщений лучше сначала собрать все выходные данные.Std :: vector может быть достаточно.Или веревка из ниток.Избегайте копирования сообщения в больший буфер снова и снова.Самое большее, скопируйте его один раз в конце, когда у вас есть все кусочки.Использование writev () для записи списка буферов вместо копирования их всех в один буфер также может быть решением.

Что касается лучшего протокола ... Что лучше?Простая отправка данных в двоичном формате является самой быстрой, но она прервется, если у вас будут разные архитектуры или версииЧто-то вроде google protobuffers может решить эту проблему, но ценой некоторой скорости.Все зависит от ваших потребностей.

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

Вопрос очень широкий.

На тему избежания конкатенации буфера / строки, как в последовательности буферов, описанной в Повышение документации Asio "Scatter-Gather"

...