Разграничение фреймов протокола приложения с помощью .Net's NetworkStream.Read/BeginRead - PullRequest
2 голосов
/ 15 сентября 2011

Мой вопрос более общий для сетевого программирования, но поскольку я пытаюсь написать TCP-сервер Modbus (ведомый), я буду использовать его для иллюстрации своего вопроса.

В кадре Modbus TCP5-й и 6-й байт кадра дают размер кадра:байты 1 и 2: идентификатор транзакциибайты 3 и 4: идентификатор протоколабайты 5 и 6: сколько байтов осталось в кадребайт 7 - n: остальная часть кадра.

Как использовать NetworkStream.Read() / BeginRead(), как можно разграничить полученные кадры?

Я видел несколько реализаций с открытым исходным кодом, которые просто читают первые 6 байтов, анализируют байты 5 и 6, чтобы получить размер остальной части кадра, а затем читают остальную часть кадра.Но если у вас нет начального и конечного разделителей в вашем кадре, как вы узнаете, где начинается и заканчивается кадр?

Например, возможно, клиент отправил несколько символов мусора, а затем отправил хороший кадр.В этом случае, если я просто прочитаю первые 6 байтов, я пропущу хороший кадр и, возможно, будущие кадры, потому что я не синхронизирован с ритмом клиента.

Этот вопрос не совсемспецифично для Modbus, но для любого протокола, который использует поле «size» для указания размера кадра.Как вы разграничиваете рамки?

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

1 Ответ

1 голос
/ 15 сентября 2011

Клиенты не должны отправлять символы мусора в большинстве интернет-протоколов: если клиент отправляет мусор, сервер отправит сообщение об ошибке и закроет соединение. Если клиент хочет продолжить связь с сервером, ему нужно создать новое соединение и на этот раз вести себя должным образом.

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

...