Есть ли у сети Boost Asio отправка / получение каких-либо гарантий полноты данных? - PullRequest
0 голосов
/ 27 июня 2019

Я использую сокеты boost asio (UDP и TCP) для обработки пользовательского протокола между моей клиент-серверной программой.Он прекрасно работал, пока я не обнаружил, что по вызовам TCP async_send / async_recieve данные могут поступать в виде комбинированных блоков.

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

Итак, мой вопрос: есть ли гарантии полноты данных при поступлении для каждого входящего вызова?(Например, async_send 128 байтов поступает с кратностью 128 байтов, или то, как он поступает, всегда должен рассматриваться как случайный, например, если поступает 1 байт, тогда возможно 127 байтов)

В частности, означает ли это, что:

  • Данные могут поступать сцепленными или частичными для каждого вызова отправки, и мне приходится всегда обрабатывать объединенные / частичные данные вручную
  • Это верно как для UDP, так и для TCP asioсокеты?

Я искал вокруг и не смог найти никакой документации по этому вопросу, поэтому мне было интересно, есть ли у кого-нибудь идеи.

Ответы [ 2 ]

1 голос
/ 30 июня 2019

Во-первых, важно понимать, что методы boost asio socket на получение и отправку означают, что они заказали базовый сетевой стек для получения или отправки данных.По сетевому стеку это может быть Windows Socket API.

Если вы отправляете данные прямо на тот же компьютер через так называемые петлевые адреса, операционная система (если таковая имеется) может просто «передать» ее прослушивающей, то есть принимающей программе.Это сценарий, в котором вам больше всего повезет навести порядок и всегда выполнить все случаи.

Однако, если вы хотите, чтобы вы обращались к другому компьютеру или операционная система была в настроении, у вас будут другиеПоведение:

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

Итак, вкратце о TCP: вы можете убедиться в полноте данных, ожидая определенной точки в ваших данных async_read_until как раз для этого случая.Данные от нескольких вызовов отправки могут быть в одном приеме, или многие

UDP был спроектирован так, чтобы иметь низкую задержку в отличие от TCP, но без его упорядочения и гарантий полноты.Поэтому, когда вы отправляете дейтаграмму UDP, т.е. пакет, ОС и сетевой адаптер обычно пытаются отправить ее как можно скорее.Однако на пути к другому компьютеру Интернет может потерять его или задержать один пакет до тех пор, пока тот, который вы отправите после первого, так, чтобы данные, отправленные позже, могли быть получены позже, тогда как вы также можете получить отправленный первым,позже или нет.Но когда вы получаете дейтаграмму, она завершается сама по себе.

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

0 голосов
/ 01 июля 2019

Итак, после еще одного тестирования вот что я сделал вывод: ответ - нет.Boost Asio Sockets не обладает магией, которая может обеспечить полноту данных сверх того, что применяются протоколы TCP / UDP.

Редактировать: Итак, вот еще мое исследование:

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

Для UDP , поскольку это пакет дейтаграммы, если пакет поступает, он гарантированно будет независимым и полным.Таким образом, нет необходимости обрабатывать частичные или комбинированные пакеты.

...