Кратко

  • Network Virtual Terminal задал узкое общее представление: CR LF означал новую строку, CR NUL — только возврат каретки, а отдельный CR в обычном NVT ASCII не допускался.
  • Байт вслед за CR завершал решение; отправитель выбирал общее действие, получатель проверял его локально и переводил в правила своей системы.
  • RFC 1123 уточнил поведение клавиши Enter, Binary отключил обработку конца строки, а Net-Unicode сохранил CRLF и стал избегать CR NUL.

Незавершённый возврат

В модели принтера NVT Carriage Return возвращает позицию печати к левому краю той же строки. Line Feed опускает её на строку, сохраняя горизонтальную координату. Последовательность CR LF объединяет два движения в функцию новой строки.

Реальные терминалы и операционные системы делали это по-разному. Одни устройства умели разделять движения, другие связывали их. Локальная строка могла завершаться CR, LF, парой символов или границей записи. Если получатель немедленно исполнял CR, последующий LF мог превратиться во второе независимое действие. Если он ждал, одиночному CR требовался явный конец.

RFC 318 предложил в 1972 году удержать CR и прочитать следующий знак. LF выбирал новую строку. Для одного возврата каретки отправитель передавал CR NUL. NUL ничего не делал с виртуальным принтером, зато закрывал развилку.

Нулевое действие не означало отсутствие информации. В этой позиции байт утверждал, что LF к предыдущему CR не относится.

Общий слой без общего железа

RFC 854 сделал Network Virtual Terminal исходным состоянием Telnet. Каждый host отображал своё устройство или process в скромную общую модель, а принятые действия — обратно в локальную среду. Полный каталог свойств удалённого терминала не требовался.

Общая часть оставалась тонкой: NUL не вызывал действия, LF двигал вертикально, CR возвращал к левому полю. Ширина, длина страницы, buffering, кодировка и terminal driver сохранялись у конечных систем.

В месте двусмысленности правило становилось строгим. CR LF следовало считать одним символом новой строки; CR NUL обозначал возврат без перехода; CR в прочих контекстах обычного NVT ASCII нужно было исключить. Требование действовало в обоих направлениях.

Получив CR NUL, Telnet удалял NUL до отображения NVT в локальный набор символов. Значит, этот байт принадлежал сетевому представлению данной mode, а не обязательно application payload. Но из этого нельзя выводить право удалять NUL в любом потоке.

Enter вернул локальную неоднозначность

Описание printer output не до конца отвечало, что User Telnet должен послать после нажатия Return или Enter. Это запрос функции конца строки или буквальный CR клавиатуры для character-oriented программы?

RFC 1123 зафиксировал расхождение: одни clients посылали CR LF, другие CR NUL. ASCII server должен был давать обеим последовательностям эффект локальной клавиши конца строки, если они пришли как terminal input. Для не-ASCII host такое равенство могло лишить пользователя настоящего отдельного CR.

Уточнение разделило контексты. User Telnet обязан уметь передавать CR LF, CR NUL и LF. ASCII client желательно давать пользовательский выбор и по умолчанию применять CR LF для end-of-line key. Для server output и текста другого application protocol, перенесённого через Telnet, конец строки обязан быть CR LF.

Server затем выполнял локальное отображение. Raw mode мог отдать приложению CR; formatted mode применял системное правило строки. Требовалось равенство поведения на границе терминала, а не одинаковые байты во всех внутренних структурах.

Binary менял владельца байтов

Binary option в RFC 856 согласуется отдельно для каждого направления. Она начинает действовать только после запроса и подтверждения. Обычные octets становятся восьмибитными данными; IAC всё равно открывает команды Telnet и удваивается для значения 255 в данных.

RFC 1123 проводит чёткую границу: в Binary нет преобразования конца строки. Нельзя заменять CR на CR NUL или CR LF. Это не NVT с расширенным алфавитом, а другой interpreter.

В NVT ASCII CR начинает двухбайтовое решение. В Binary CR, LF и NUL остаются данными приложения. Фильтр, удаляющий NUL после CR по старой привычке, повреждает поток; вставка NUL повреждает его так же.

Для расследования нужны исходные octets, направление и negotiation state. Отрисованный текст скрывает, какая сторона и какая mode имели право на преобразование.

Linemode приблизил редактирование

RFC 1184 позволил client редактировать строку локально, чтобы не ждать сетевого эха для каждого знака. При активном EDIT обычный локальный terminator передавался как CR LF.

Без EDIT carriage return шёл как CR NUL, line feed — как LF, а специальная клавиша завершения строки — как CR LF. За server output по-прежнему отвечал server: CR LF для новой строки, CR NUL для одного возврата, LF для одного вертикального движения.

Работу можно было перенести ближе к пользователю ради latency, не отдавая client право переопределять смысл чужого вывода. Размещение обработки и семантическая власть оставались разными решениями.

Unicode сохранил строку и сузил исключение

RFC 5198 связал историю NVT ASCII с Net-Unicode. Форматом стал UTF-8, но концом строки остался CRLF. Сохранилось и структурное требование: CR должен непосредственно сопровождаться LF или NUL.

При этом CR NUL рекомендовано избегать. Современные combining characters и markup заменили многие приёмы overstrike и printer layout, а NUL опасен для сред, где он завершает строку. Отдельный возврат каретки потерял прежнюю ценность.

Это не отмена исходного решения. CR NUL действительно ограничивал двусмысленность в старой модели; позднее из общего слоя сохранилась глубоко установленная граница CRLF, а редкий эффект можно было отвести на периферию.

IANA Telnet Options registry хранит коды Binary, Linemode и carriage-return options. Реестр подтверждает словарь, но не нынешнее распространение и не соответствие продуктов.

После нормализации доказательство не восстановить

Распределение контроля было небольшим: sender выбирал действие NVT, receiver проверял соседний байт и переводил локально, новый parser получал власть через согласование.

Сбой возникает, когда промежуточная система опережает этот порядок. Gateway унифицирует строки до чтения mode, string API обрывается на NUL, client заранее отождествляет Enter с newline, журнал оставляет только видимый экран. После уничтожения различающего байта человеческое объяснение не вернёт протокольный факт.

Источники и пределы доказательств

Документы устанавливают модель, уточнения, согласованные исключения и зарегистрированные термины. Они не измеряют современное использование, не сертифицируют продукты и не доказывают единство всех исторических реализаций. Значение CR NUL ограничено известными mode, направлением и функцией.