Понимание протокола ZMODEM
Вопрос
Мне нужно включить в мою программу базовые процедуры отправки и получения файлов, и это должно осуществляться через протокол ZMODEM.Проблема в том, что у меня возникли проблемы с пониманием спецификации.
Для справки, вот спецификация.
Спецификация не определяет различные константы, так что вот заголовочный файл из Google.
Мне кажется, что в этом документе осталось много важных вещей, не определенных:
- Это постоянно ссылается на ZDLE-кодировку, но что это? Когда именно я им пользуюсь, а когда нет?
- После фрейма данных ZFILE передаются метаданные файла (имя файла, дата изменения, размер и т.д.).За ним следует блок ZCRCW, а затем блок, тип которого не определен в соответствии со спецификацией.Блок ZCRCW предположительно содержит 16-битный CRC, но спецификация не определяет, на основе каких данных вычисляется CRC.
Он не определяет используемый им полином CRC.Я случайно узнал, что CRC32 poly является стандартным CRC32, но мне не повезло с CRC16 poly.Неважно, я нашел это методом проб и ошибок.Значение CRC16 poly равно 0x1021.
Я поискал справочный код, но все, что я могу найти, - это нечитаемые, недокументированные файлы C начала 90-х.Я также нашел этот набор документов из MSDN, но он крайне расплывчатый и противоречит тестам, которые я запускал: http://msdn.microsoft.com/en-us/library/ms817878.aspx (возможно, вам потребуется просмотреть это с помощью Кэш Google)
Чтобы проиллюстрировать мои трудности, приведу простой пример.Я создал на сервере текстовый файл, содержащий "Hello world!", и он называется helloworld.txt.
Я инициирую передачу с сервера следующей командой:
sx --zmodem helloworld.txt
При этом серверу предлагается отправить следующий кадр ZRQINIT:
2A 2A 18 42 30 30 30 30 30 30 30 30 30 30 30 30 **.B000000000000
30 30 0D 8A 11 00.Š.
Три проблемы, связанные с этим:
- Являются ли байты заполнения (0x2A) произвольными?Почему здесь их два, но в других случаях только один, а иногда и ни одного?
- В спецификации не упоминается [CR] [LF] [XON] в конце, но в статье MSDN упоминается.Почему он там находится?
- Почему в [LF] установлен бит 0x80?
После этого клиенту необходимо отправить фрейм ZRINIT.Я почерпнул это из статьи MSDN:
2A 2A 18 42 30 31 30 30 30 30 30 30 32 33 62 65 **.B0100000023be
35 30 0D 8A 50.Š
В дополнение к проблеме с флагом [LF] 0x80, у меня есть еще две проблемы:
- Почему на этот раз не включен [XON]?
Вычисляется ли CRC на основе двоичных данных или шестнадцатеричных данных ASCII?Если это двоичные данные, я получаю 0x197C, а если это шестнадцатеричные данные ASCII, я получаю 0xF775;ни то, ни другое не является тем, что на самом деле находится во фрейме (0xBE50).(Решаемая;это зависит от того, какой режим вы используете.Если вы находитесь в режиме BIN или BIN32, это CRC двоичных данных.Если вы находитесь в шестнадцатеричном режиме ASCII, это CRC того, что представлено шестнадцатеричными символами ASCII.)
Сервер отвечает фреймом ZFILE:
2A 18 43 04 00 00 00 00 DD 51 A2 33 *.C.....ÝQ¢3
ОК.В этом есть смысл.Если я вычислю CRC32 из [04 00 00 00 00 00], я действительно получу 0x33A251DD.Но теперь у нас нет НИКАКОГО [CR] [LF] [XON] в конце.Почему это происходит?
Сразу после этого кадра сервер также отправляет метаданные файла:
68 65 6C 6C 6F 77 6F 72 6C 64 2E 74 78 74 00 31 helloworld.txt.1
33 20 32 34 30 20 31 30 30 36 34 34 20 30 20 31 3 240 100644 0 1
20 31 33 00 18 6B 18 50 D3 0F F1 11 13..k.PÓ.ñ.
У этого даже нет заголовка, он просто переходит прямо к данным.Ладно, я могу с этим жить.Однако:
- У нас есть наш первый загадочный кадр ZCRCW:[18 6B].Какой длины этот кадр?Где находятся данные CRC, и является ли это CRC16 или CRC32?Это нигде не определено в спецификации.
- В статье MSDN указано, что за [18 6B] должно следовать [00], но это не так.
- Тогда у нас есть фрейм с неопределенным типом:[18 50 D3 0F F1 11].Это отдельный фрейм или это часть ZCRCW?
Клиент должен ответить фреймом ZRPOS, опять же взятым из статьи MSDN:
2A 2A 18 42 30 39 30 30 30 30 30 30 30 30 61 38 **.B0900000000a8
37 63 0D 8A 7c.Š
Те же проблемы, что и с фреймом ZRINIT: CRC ошибочен, в [LF] установлен бит 0x80, а в [XON] нет.
Сервер отвечает фреймом ZDATA:
2A 18 43 0A 00 00 00 00 BC EF 92 8C *.C.....¼ï’Œ
Те же проблемы, что и с ZFILE:с CRC все в порядке, но где [CR] [LF] [XON]?
После этого сервер отправляет полезную нагрузку файла.Поскольку это короткий пример, он умещается в одном блоке (максимальный размер - 1024).:
48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0A Hello world!.
Из того, что, кажется, упоминается в статье, полезные нагрузки экранируются с помощью [ZDLE] .Итак, как мне передать байт полезной нагрузки, который совпадает со значением [ZDLE]?Существуют ли какие-либо другие подобные значения?
Сервер завершается этими кадрами:
18 68 05 DE 02 18 D0 .h.Þ..Ð
2A 18 43 0B 0D 00 00 00 D1 1E 98 43 *.C.....Ñ.˜C
Я совершенно запутался в первом вопросе.Второй имеет такой же смысл, как фреймы ZRINIT и ZDATA.
Решение
Мой приятель чудес, если вы реализуете время машина.
Я не знаю, что могу ответить на все ваши вопросы - я никогда На самом деле пришлось сам реализовать ZModem - но вот несколько ответов:
Из того, что упоминается статья, полезные нагрузки сбежались с [Тьд]. Так как я могу передать байт полезной нагрузки, который будет соответствовать Значение [ZDLE]? Есть ли какие-либо другие значения?
Это явно адресовано в документе, который вы связаны с Начало ваших вопросов, в котором говорится:
.The ZDLE character is special. ZDLE represents a control sequence of some sort. If a ZDLE character appears in binary data, it is prefixed with ZDLE, then sent as ZDLEE.
Это постоянно относится к кодированию ZDLE, но что это? Когда точно Я использую это, и когда я не использую его?
В старые времена некоторые «контрольные персонажи» были использованы для контроля канал связи (отсюда название). Например, отправка Xon / Xoff символы могут приостановить передачу. ZDDLE используется для ухода символы, которые могут быть проблематичными. Согласно спецификации, это Персонажи, которые сбежаются по умолчанию:
.ZMODEM software escapes ZDLE, 020, 0220, 021, 0221, 023, and 0223. If preceded by 0100 or 0300 (@), 015 and 0215 are also escaped to protect the Telenet command escape CR-@-CR. The receiver ignores 021, 0221, 023, and 0223 characters in the data stream.
Я оглянулся на справочный код, но все, что я могу найти, являются Нечитаемые, недокументированные C файлы с начала 90-х годов.
включает в себя этот код для кода Пакет lrzsz ? Это все еще Широко доступно на большинстве дистрибутивов Linux (и удивительно удобно Для передачи файлов над установленным соединением SSH).
Есть несколько других реализаций, в том числе Несколько в программном обеспечении, перечисленном на FreeCode , в том числе qodem , Syncterm , Mbse и другие. Я верю, что Syncterm Реализация написана как библиотека, которая может быть разумной использовать из вашего собственного кода (но я не уверен).
Вы можете найти дополнительный код, если вы увидите пожилые коллекции MS-DOS программное обеспечение.
Другие советы
Я не могу винить тебя.Руководство пользователя организовано не так, чтобы это было удобно пользователю
Являются ли байты заполнения (0x2A) произвольными?
Нет, со страницы 14,15:
Двоичный заголовок начинается с последовательности ZPAD, ZDLE, ZBIN.
Шестнадцатеричный заголовок начинается с последовательности ZPAD, ZPAD, ZDLE, ZHEX.
.
В спецификации не упоминается [CR] [LF] [XON] в конце, но в статье MSDN упоминается.Почему он там находится?
Страница 15
* * ZDLE B ТИПА F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON .Почему в [LF] установлен бит 0x80?
Не уверен.Из термина Tera я получил оба управляющих символа, XORed с 0x80 (8D 8A 11)
У нас есть наш первый загадочный кадр ZCRCW:[18 6B].Какой длины этот кадр?Где находятся данные CRC, и является ли это CRC16 или CRC32?Это нигде не определено в спецификации.
ZCRCW - это не верхний колонтитул или тип фрейма, это скорее нижний колонтитул, который сообщает получателю, чего ожидать дальше.В данном случае это нижний колонтитул подпакета данных, содержащего имя файла.Это будет 32-битная контрольная сумма, потому что вы используете двоичный заголовок типа "C".
- ЗДЛЕ C ТИП F3/P0 F2/P1 F1/P2 F0/P3 КРР-1 КРР-2 КРР-3 КРР-4
.
Тогда у нас есть фрейм с неопределенным типом:[18 50 D3 0F F1 11].Это отдельный фрейм или это часть ZCRCW?
Это CRC для подпакета данных ZCRCW.Это 5 байт, потому что первый - 0x10, управляющий символ, который должен быть экранирован ZDLE.Я не уверен, что такое 0x11.
и там нет [XON].
XON предназначен только для шестнадцатеричных заголовков.Вы не используете его для двоичного заголовка.
- УСТАНОВИТЕ ТИП F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 .Итак, как мне передать байт полезной нагрузки, который совпадает со значением [ZDLE]?
18 58 (ОН ЖЕ ЗДЛИ)
18 68 05 DE 02 18 D0
Это нижний колонтитул подфрейма данных.Следующие 5 байтов - это CRC (последний байт закодирован в ZDLE).