Я пишу очень специфический протокол приложения, чтобы обеспечить связь между двумя узлами. Узел 1 - это встроенная платформа (микроконтроллер), а узел 2 - это обычный компьютер.
Такой протокол определяет сообщения переменной длины. Это означает, что иногда узел 1 отправляет сообщение размером 100 байтов узлу 2, тогда как в другой раз он отправляет сообщение длиной 452 байта.
Такой протокол должен быть независимым от того, как сообщения передаются. Например, одно и то же сообщение может быть отправлено через USB, Bluetooth и т. Д.
Предположим, что сообщение протокола определено как:
| Length (4 bytes) | ...Payload (variable length)... |
Я борюсь за то, как получатель может распознать, как долго это входящее сообщение. До сих пор я думал о 2 подходах.
1-й подход
Отправитель сначала отправляет длину (4 байта, всегда фиксированный размер), а затем сообщение.
Например, отправитель делает что-то вроде этого:
// assuming that the parameters of send() are: data, length of data
send(msg_length, 4)
send(msg, msg_length - 4)
В то время как сторона получателя делает:
msg_length = receive(4)
msg = receive(msg_length)
Это может быть приемлемо для некоторых "физических протоколов" (например, UART), но с более сложными (например, USB) передачей длины с отдельным пакетом может возникнуть некоторая служебная нагрузка. Причина в том, что дополнительный USB-пакет (с управляющими данными, а также ACK-пакетами) требуется передавать только для 4 байтов.
Однако при таком подходе сторона получателя довольно проста.
2-й подход
Альтернативой может быть то, что получатель продолжает получать данные в буфер и в какой-то момент пытается найти правильное сообщение. Действительный означает: сначала найти длину сообщения, а затем его полезную нагрузку.
Скорее всего, этот подход требует добавления байтов в начало сообщения в начале сообщения, чтобы получатель мог использовать их, чтобы определить, где начинается сообщение.