Практически всё упомянули. И похоже парня совсем подзапугали.

Для упрощения ситуации скажу следующее. Чем вероятнее возникновение ошибки, чем большие размеры передаются, чем длинее линия, чем выше скорость и выше требования к надёжности передачи - тем сложнее протокол.
Я делал двухсторонние эффективные протоколы с вероятностью битовой ошибки более 0,3%.

Там было всё перечисленное только после метки начала - команды кодировались кодом хеминга. Но это же реально не всегда надо.
Но таймауты я применяю практически всегда.
А вот есть момент который не упомянули.
При высокой скорости передачи и при требовании высокой пропускной способности применяют следующее. Пакеты (типовые уже были расписаны) нумеруются псевдослучайным образом.
Зачем?
Дело в том, что при описанной структуре пакета, от принимающей стороны требуется подтверждение правильности приёма. Если передача - дуплексная, то, во-первых это дополнительно нагружает линию, а во вторых передающий канал простаивает в ожидании ответа.
Если нумеровать пакеты, то ответ передаётся только на битый пакет (с указанием его номера) и он повторяется.
Мне очень нравится эта область деятельности и при грамотном протоколе размер избыточности информации можно свести к единицам процентов. Даже при отсутствии сжатия. Да ещё скажу при самом крутом протоколе и в разности скоростей 115/32 (От компа/Линия) рост скорости от размера буфера затормаживается начиная с 1кб.