Понимание протокола ZMODEM

Мне нужно включить в мою программу базовые процедуры отправки и получения файлов, и это должно быть через протокол ZMODEM. Проблема в том, что у меня проблемы с пониманием спецификации.

Для справки, вот спецификация.

Спецификация не определяет различные константы, поэтому вот заголовочный файл из Google.

Мне кажется, что в этом документе много важных вещей осталось неопределенными:

  • Там постоянно упоминается ZDLE-кодирование, но что это такое?Когда именно я его использую, и когда я не использую его?
  • После кадра данных ZFILE передаются метаданные файла (имя файла, дата изменения, размер и т. д.). За ним следует блок ZCRCW, а затем блок, тип которого не определен согласно спецификации. Блок ZCRCW предположительно содержит 16-битную CRC, но спецификация не определяет, на каких данных вычисляется CRC.
  • Он не определяет полином CRC, который он использует. Я случайно узнал, что полигон CRC32 является стандартным CRC32, но мне не повезло с полигоном CRC16. Ничего, я нашел это методом проб и ошибок. Полигон CRC16 равен 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

OK. Это имеет смысл. Если я вычислю CRC32 [04 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.

11
задан mattdm 14 March 2012 в 21:56
поделиться