Использование Boost.Asio для получения «всего пакета» - PullRequest
2 голосов
/ 06 июня 2010

У меня есть TCP-клиент, подключающийся к моему серверу, который отправляет необработанные пакеты данных. Как, используя Boost.Asio, я могу получить «целый» пакет каждый раз (конечно, асинхронно)? Предположим, что эти пакеты могут быть любого размера вплоть до полного размера моей памяти.

По сути, я хочу избежать создания буфера статического размера.

Ответы [ 3 ]

3 голосов
/ 06 июня 2010

Обычно, когда вы создаете собственный протокол поверх TCP / IP, вы используете простой формат сообщения, где первые 4 байта представляют собой целое число без знака, содержащее длину сообщения, а остальные - данные сообщения. Если у вас есть такой протокол, то цикл приема такой же простой, как показано ниже (не уверен, что такое нотация ASIO, так что это просто идея)

for(;;) {
  uint_32_t len = 0u;
  read(socket, &len, 4); // may need multiple reads in non-blocking mode
  len = ntohl(len);
  assert (len < my_max_len);
  char* buf = new char[len];
  read(socket, buf, len); // may need multiple reads in non-blocking mode
  ...
}
3 голосов
/ 06 июня 2010

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

2 голосов
/ 06 июня 2010

обычно, когда вы делаете асинхронный ввод-вывод, ваш протокол должен поддерживать его.Один из простых способов - это префикс байтового массива с его длиной на логическом уровне и иметь буфер чтения кода до тех пор, пока не будет готов полный буфер для синтаксического анализа.в конечном итоге эта логика разбросана повсюду (подумайте о чтении строки с нулевым символом в конце и о том, что это значит, если вы просто получаете ее часть каждый раз, когда select / poll возвращает)

...