2016-11-04 1 views
1

Я хочу отправить пакеты с переменным размером между 2 операционными системами Linux по внутренней сети. Пакет имеет размер переменной, а его длина и CRC указаны в заголовке, который также отправляется вместе с пакетом. Что-то примерно как-Отправка пакетов с переменным размером по сети с использованием TCP/IP

struct hdr { 
    uint32 crc; 
    uint32 dataSize; 
    void *data; 
}; 

Я использую CRC на прикладном уровне, чтобы преодолеть присущую limitation of TCP checksums

Проблемы у меня есть, есть шанс, что само поле dataSize повреждено, в этом случае , Я не знаю, где начинается следующий пакет? Cos в ресивере, когда я читаю буфер сокета, я читал n такие пакеты рядом друг с другом. Так что dataSize - единственный способ, которым я могу правильно добраться до следующего пакета.

Некоторые идеи у меня есть to-

  1. Restart соединение при обнаружении несоответствия CRC.
  2. Совокупность X таких пакетов в один большой пакет фиксированного размера и отбрасывает большой пакет, если обнаружена ошибка CRC. Большой пакет должен удостовериться, что мы проиграем < = sizeof одного пакета в случае ошибок

Любые другие идеи для этих пакетов с переменным размером?

ответ

1

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

Другим способом, кроме байтов длины, является использование маркеров. Начало сообщения и окончание сообщения. Приложение, когда сталкивается с Start-of-Message, должно начинать сбор данных до тех пор, пока не будет принят байт End-of-Message, а затем обработать сообщение. Это требует, чтобы сообщение соответствовало маркерам.

1

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

Когда мы использовали передачи последовательной линии, ошибки были частые (один или два каждые несколько килобайт). Мы использовали старый добрый Kermit с CRC и размером пакета около 100 байт, и этого было достаточно: я много раз сталкивался с неудачной передачей, потому что линия отключилась, но никогда не была корректной передачей с плохим файлом.

С существующими сетями, если у вас очень плохие линии, уровень аппаратного обеспечения не так уж плох, и в любом случае уровень линии передачи данных уровня 2 уже имеет контрольную сумму для управления тем, что каждый пакет не был изменен между двумя узлами. HDLC обычно используется на этом уровне, и он использует нормальную контрольную сумму CRC16 или CRC32, которая является очень правильной контрольной суммой.

Таким образом, контрольная сумма, как уровень TCP не предназначен для обнаружения случайных ошибок в потоке байтов, а просто в качестве последней линии обороны для неожиданных ошибок, для Exemple если маршрутизатор злится из-за поражения электрическим током и посылает полный мусор. У меня нет статистических данных, но я уверен, что количество ошибок, достигающих уровня TCP, уже очень мало.Говоря иначе, не беспокойтесь об этом: если вы не имеете дело с высокочувствительными данными, и в этом случае я бы предпочел иметь два разных канала: первый для данных, последний для глобальной контрольной суммы - достаточно TCP/IP.

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

  • закрыть соединение
  • открыть новый
  • перезапуск после последнего пакета правильно обменены (если это имеет смысл) или просто продолжать посылать новые пакеты, если вы можете

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

И не забудьте полностью указать порядок байтов и размер crc и datasize ...

Смежные вопросы