Попытайтесь рассмотреть свою "более сложную" версию другими, спустя несколько недель после записи его. Судите сложность на том, насколько трудный он для Вас, чтобы считать и объяснить его другим и их реакцию на код.
Хорошо, я разобрался как это сделать (хитроумно, но он выполняет свою работу).
Просто удалить заголовки Ethernet, IP и TCP, оставив вам сообщение с «необработанными» данными. Заглянув внутрь сообщения, легко определить, является ли оно началом HTTP-пакета, посмотрев на «HTTP / 1.1 ...» в начале пакета. Это указывает на то, что пакет является началом потока HTTP / большего пакета / любого другого. Вы также можете выполнить простой синтаксический анализ, чтобы прочитать поле «Content-Length», которое представляет собой общую длину всего HTTP-пакета.
Вы также можете использовать номера IP-адреса источника / назначения и порта для формирования уникального идентификатора для ссылки . Поэтому после получения пакета заголовка обратите внимание на эти 4 вещи (SRCIP, SRCPORT, DESTIP, DESTPORT). В следующий раз, когда вы получите пакет, соответствующий этой комбинации порт / IP, вы можете проверить, является ли это следующей частью HTTP-пакета. Вы можете использовать порядковые номера для некоторой проверки и, возможно, других вещей, но в целом пакеты в порядке, так что все в порядке. Я думаю, что для каждого HTTP-потока открывается новый порт, поэтому вы не должны получать случайные пакеты, которые не являются частью потока, но это может быть областью, подверженной ошибкам.
В любом случае, как только вы получили этот пакет, снова удалите заголовки и получите необработанное сообщение. Добавьте его в уже известную часть сообщения. Если длина всего полученного сообщения равна длине, считанной из поля «Content-Length», пакет готов!
Этот метод, очевидно, подвержен огромному количеству ошибок, но мне не нужен чрезвычайно надежный способ сделать это. Я думал, что отвечу на свой вопрос, если кто-то еще столкнется с этой же проблемой в будущем! Удачи с нюханием: D
Вы не должны использовать какую-либо информацию с уровня TCP для определения границ HTTP-запроса. TCP обеспечивает надежную службу потока байтов; вы не можете видеть никаких полей или флагов в TCP, которые помогли бы с этим, потому что их нет.
Чтобы определить, где находятся границы в HTTP-запросе, вы должны следовать RFC 2616. Границы четко определены, и вы можете определить их, анализируя полученные данные.
В каждом пакете TCP начало данных полезной нагрузки находится сразу после заголовка TCP, а конец данных полезной нагрузки является концом IP-пакета.
Конец заголовка TCP легко найти - Смещение данных
- это 4-битное поле в заголовке, которое содержит длину заголовка в 32-битных словах (поэтому умножьте его на 4, чтобы получить длину в 8-битных байтах).
Используйте TCP порядковые номера из поля Sequence
для объединения полезных данных в правильном порядке. Обратите внимание, что в случае повторной передачи могут быть дубликаты.
TCP - это протокол потока , а не пакетный протокол. Уровень приложения (то есть вы) получает поток данных, а не группу пакетов. Вы просто продолжаете читать байты из потока, и вы получите всю полезную нагрузку http, а TCP выполняет проверку ошибок, повторную отправку и т. Д.
Нам пришлось работать над решением той же проблемы. Нам удалось извлечь некоторые из основных функций в проект с открытым исходным кодом.
http://code.google.com/p/pcap-reconst/
Пожалуйста, проверьте его и дайте мне знать, поможет ли тебя нет.
Вы можете использовать код проекта с открытым исходным кодом под названием Xplico: http://www.xplico.org