Получать пакет по пакетным данным из сокета TCP? - PullRequest
9 голосов
/ 07 июня 2011

У меня есть сокет TCP, по которому я получаю видеопоток. Я хочу получать данные как пакет за пакетом из сокета, чтобы я мог удалить заголовок пакета и сохранить данные единственного потока. Как я могу это сделать ??

любая помощь будет оценена.

Ответы [ 5 ]

15 голосов
/ 07 июня 2011

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

  • Когда вы хотите отправить «пакет», в первую очередь включите длину
  • Когда вы читаете вещи из сокета, убедитесь, что вы читаетенаименьшая длина

Ваше сообщение может быть:

|Message Length:4bytes|Additional header Information:whatever1|Message Data:whatever2|

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

3 голосов
/ 07 июня 2011

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

Алгоритм:

  1. Инициализировать пустой буфер.
  2. Проверка буфера для полного пакета.
  3. Если найдено, удалите полный пакет из начала буфера и обработайте его.
  4. Если не найдено, добавьте данные из recv() в буфер и перейдите к # 2.

То, что содержит «полный пакет», должно определяться протоколом потокового видео.

2 голосов
/ 07 июня 2011

Как уже упоминалось, TCP - это потоковый протокол. Это означает, что с точки зрения API нет понятия «пакет». Как пользователь, все, что вы можете ожидать, это поток данных.

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

Возможно, вы сможете использовать необработанные сокеты для получения необработанных IP-пакетов, но это будет означать, что вам придется переопределять большую часть стека TCP (например, отправлять ACK и настраивать размер окна), чтобы удаленный конец работал правильно. Вы не хотите этого делать.

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

2 голосов
/ 07 июня 2011

TCP - это потоковый протокол, и он не гарантирует, что при вызове функции чтения сокетов вы получите один полный пакет. UDP или SCTP являются пакетно-ориентированными протоколами и гарантируют это. Для TCP вы можете получить часть пакета или несколько пакетов одновременно. Вы должны создать собственный протокол приложения поверх TCP и вручную фрагментировать / дефрагментировать сообщения.

1 голос
/ 07 июня 2011

Вы уверены в этом подходе? По моему мнению, эта «предварительная обработка» привнесет дополнительные издержки в систему. И, конечно, это обрабатывается нижним уровнем (Читать о модели OSI), поэтому изменить его нелегко. Обратите внимание, что большинство существующих потоковых протоколов уже оптимизированы для достижения наилучшей производительности.

...