Программирование сокетов: проверка ошибок сообщения.Кто-нибудь знает фантом причины? - PullRequest
1 голос
/ 07 июля 2011

Прямо сейчас у меня есть инфраструктура связи, состоящая из клиента и сервера.

Клиент подключается к серверу с помощью стандартных сокетов TCP.

У меня есть структура сообщения, которая выглядит следующим образом:

4 bytes -- Message size
n bytes -- Message
4 bytes -- CRC32 checksum

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

Если сообщение не проходит проверку CRC32, соединение разрывается и устанавливается новое соединение.

Мой вопрос: почему, черт возьми, я получаю случайные сбои CRC32?

Без видимой причины,даже если клиент и сервер находятся на одном компьютере с использованием петлевого адреса (127.0.0.1).

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

Ответы [ 2 ]

6 голосов
/ 07 июля 2011

Вы не показывали никакого кода, поэтому я могу только догадываться.

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

  • . Функции некоторых контрольных сумм не работают для некоторых входных данных, посколькуневерно

Первое, вероятно, то, что происходит.Вы читаете некоторые данные и возвращаете recv / read с меньшим количеством прочитанных байтов, чем ожидаете.

Кроме того, вы действительно понимаете, что пытаетесь делать правильно?

  • Фрейм Ethernet имеет поле CRC-32
  • Пакет IPv4 имеет контрольную сумму заголовка 16b
  • Сегмент TCP имеет контрольную сумму 16-b, охватывающую как заголовок, данные, а затем некоторые
  • Ваши данные также будут иметь CRC-32

Вы понимаете, что это избыточно, верно?

0 голосов
/ 08 июля 2011

Кстати, правильный способ проверки контрольной суммы в получателе - это вычислить ее по всему сообщению и контрольной сумме , рассматриваемой совместно как более длинное сообщение.Результат должен быть нулевым.Таким образом, вы включаете саму контрольную сумму в расчет.Неправильный способ сделать это - вычислить контрольную сумму по сообщению, исключая контрольную сумму, а затем сравнить с полученной контрольной суммой.

...