Pergunta

Preciso incluir rotinas básicas de envio e recebimento de arquivos em meu programa, e isso precisa ser por meio do protocolo ZMODEM.O problema é que estou tendo problemas para entender as especificações.

Para referência, aqui está a especificação.

A especificação não define as várias constantes, então aqui está um arquivo de cabeçalho do Google.

Parece-me que há muitas coisas importantes indefinidas nesse documento:

  • Refere-se constantemente à codificação ZDLE, mas o que é? Quando exatamente devo usá-lo e quando não devo usá-lo?
  • Após um quadro de dados ZFILE, os metadados do arquivo (nome do arquivo, data de modificação, tamanho, etc.) são transferidos.Isto é seguido por um bloco ZCRCW e então um bloco cujo tipo é indefinido de acordo com a especificação.O bloco ZCRCW supostamente contém um CRC de 16 bits, mas a especificação não define em quais dados o CRC é calculado.
  • Ele não define o polinômio CRC que usa.Descobri por acaso que o poli CRC32 é o CRC32 padrão, mas não tive tanta sorte com o poli CRC16. Deixa pra lá, descobri por tentativa e erro.O poli CRC16 é 0x1021.

Procurei código de referência, mas tudo que encontrei foram arquivos C ilegíveis e não documentados do início dos anos 90.Também encontrei este conjunto de documentos do MSDN, mas é dolorosamente vago e contraditório com os testes que executei: http://msdn.microsoft.com/en-us/library/ms817878.aspx (talvez você precise ver isso através Cache do Google)

Para ilustrar minhas dificuldades, aqui está um exemplo simples.Criei um arquivo de texto simples no servidor contendo "Hello world!" e se chama helloworld.txt.

Eu inicio a transferência do servidor com o seguinte comando:

sx --zmodem helloworld.txt

Isso solicita que o servidor envie o seguinte quadro ZRQINIT:

2A 2A 18 42 30 30 30 30 30 30 30 30 30 30 30 30   **.B000000000000
30 30 0D 8A 11                                    00.Š.

Três problemas com isso:

  • Os bytes de preenchimento (0x2A) são arbitrários?Por que há dois aqui, mas em outros casos há apenas um, e às vezes nenhum?
  • A especificação não menciona [CR] [LF] [XON] no final, mas o artigo do MSDN menciona.Por que está aí?
  • Por que o [LF] tem o bit 0x80 definido?

Depois disso, o cliente precisa enviar um quadro ZRINIT.Peguei isso no artigo do MSDN:

2A 2A 18 42 30 31 30 30 30 30 30 30 32 33 62 65   **.B0100000023be
35 30 0D 8A                                       50.Š

Além do problema do sinalizador [LF] 0x80, tenho mais dois problemas:

  • Por que [XON] não está incluído desta vez?
  • O CRC é calculado nos dados binários ou nos dados hexadecimais ASCII?Se estiver nos dados binários, obtenho 0x197C e, se estiver nos dados hexadecimais ASCII, obtenho 0xF775;nenhum deles é o que realmente está no quadro (0xBE50). (Resolvido;segue qualquer modo que você esteja usando.Se você estiver no modo BIN ou BIN32, é o CRC dos dados binários.Se você estiver no modo hexadecimal ASCII, é o CRC representado pelos caracteres hexadecimais ASCII.)

O servidor responde com um quadro ZFILE:

2A 18 43 04 00 00 00 00 DD 51 A2 33               *.C.....ÝQ¢3

OK.Este faz sentido.Se eu calcular o CRC32 de [04 00 00 00 00], realmente obtenho 0x33A251DD.Mas agora não temos QUALQUER [CR] [LF] [XON] no final.Por que é isso?

Imediatamente após esse quadro, o servidor também envia os metadados do arquivo:

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Ó.ñ.

Isso nem tem cabeçalho, apenas vai direto para os dados.OK, posso viver com isso.No entanto:

  • Temos nosso primeiro quadro ZCRCW misterioso:[18 6B].Quanto tempo tem esse quadro?Onde estão os dados CRC e são CRC16 ou CRC32?Não está definido em nenhum lugar das especificações.
  • O artigo do MSDN especifica que [18 6B] deve ser seguido por [00], mas não é.
  • Então temos um quadro com um tipo indefinido:[18 50 D3 0F F1 11].Este é um quadro separado ou faz parte do ZCRCW?

O cliente precisa responder com um quadro ZRPOS, novamente retirado do artigo do MSDN:

2A 2A 18 42 30 39 30 30 30 30 30 30 30 30 61 38   **.B0900000000a8
37 63 0D 8A                                       7c.Š

Os mesmos problemas do quadro ZRINIT: o CRC está errado, o [LF] tem o bit 0x80 definido e não há [XON].

O servidor responde com um quadro ZDATA:

2A 18 43 0A 00 00 00 00 BC EF 92 8C               *.C.....¼ï’Œ

Mesmos problemas do ZFILE:o CRC está bem, mas onde está o [CR] [LF] [XON]?

Depois disso, o servidor envia a carga útil do arquivo.Como este é um exemplo curto, ele cabe em um bloco (o tamanho máximo é 1024):

48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0A            Hello world!.

Pelo que o artigo parece mencionar, as cargas úteis são escapadas com [ZDLE].Então, como faço para transmitir um byte de carga útil que corresponda ao valor de [ZDLE]?Existem outros valores como este?

O servidor termina com estes frames:

18 68 05 DE 02 18 D0                              .h.Þ..Ð
2A 18 43 0B 0D 00 00 00 D1 1E 98 43               *.C.....Ñ.˜C

Estou completamente perdido no primeiro.O segundo faz tanto sentido quanto os frames ZRINIT e ZDATA.

Foi útil?

Solução

Meu amigo quer saber se você está implementando um tempo máquina.

Eu não sei se posso responder a todas as suas perguntas -- eu nunca Na verdade tive que implementar o zmodem eu mesmo -- mas aqui estão algumas respostas:

Pelo que o artigo parece mencionar, as cargas úteis são escapadas com [ZDLE].Então, como faço para transmitir um byte de carga que corresponde ao valor de [ZDLE]?Existem outros valores como este?

Isso é explicitamente abordado no documento ao qual você vinculou no Início de suas perguntas, que diz:

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.

Refere-se constantemente à codificação ZDLE, mas o que é?Quando exatamente eu uso e quando não uso?

Antigamente, certos "caracteres de controle" eram usados para controlar o canal de comunicação (daí o nome).Por exemplo, enviando XON/XOFF Os caracteres podem pausar a transmissão.ZDLE é usado para escapar personagens que podem ser problemáticos.De acordo com a especificação, estes são Os caracteres que são escapados por padrão:

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.

Eu procurei código de referência, mas tudo o que posso encontrar são arquivos C ilegíveis e não documentados do início dos anos 90.

Isso inclui o código para o lrzsz pacote?Isso ainda é amplamente disponível na maioria das distribuições Linux (e surpreendentemente útil para transmitir arquivos através de uma conexão ssh estabelecida).

Há uma série de outras implementações por aí, incluindo vários em software listados em código livre, Incluindo qodem, termo de sincronização, MBSE, e outros.Eu acredito que Termo de sincronização implementação é escrito como biblioteca que pode ser razoavelmente fácil para usar a partir do seu próprio código (mas não tenho certeza).

Você pode encontrar código adicional se você mexer em coleções mais antigas de Software MS-DOS.

Outras dicas

Eu não posso culpar você.O manual do usuário não está organizado de maneira amigável

Os bytes de preenchimento (0x2A) são arbitrários?

Não, da página 14,15:

Um cabeçalho binário começa com a sequência ZPAD, ZDLE, ZBIN.

Um cabeçalho hexadecimal começa com a sequência ZPAD, ZPAD, ZDLE, ZHEX.

.

A especificação não menciona [CR] [LF] [XON] no final, mas o artigo do MSDN menciona.Por que está aí?

Página 15

* * ZDLE B TIPO F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON.Por que o [LF] tem o bit 0x80 definido?

Não tenho certeza.Do termo Tera, obtive XOR de ambos os caracteres de controle com 0x80 (8D 8A 11)

Temos nosso primeiro quadro ZCRCW misterioso:[18 6B].Quanto tempo tem esse quadro?Onde estão os dados CRC e são CRC16 ou CRC32?Não está definido em nenhum lugar das especificações.

O ZCRCW não é um cabeçalho ou tipo de quadro, é mais como um rodapé que informa ao receptor o que esperar em seguida.Neste caso é o rodapé do subpacote de dados que contém o nome do arquivo.Será uma soma de verificação de 32 bits porque você está usando um cabeçalho binário do tipo "C".

  • ZDLE C TIPO F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CRC-3 CRC-4

.

Então temos um quadro com um tipo indefinido:[18 50 D3 0F F1 11].Este é um quadro separado ou faz parte do ZCRCW?

Esse é o CRC do subpacote de dados ZCRCW.São 5 bytes porque o primeiro é 0x10, um caractere de controle que precisa ser escapado do ZDLE.Não tenho certeza do que é 0x11.

e não há [XON].

XON é apenas para cabeçalhos hexadecimais.Você não o usa para um cabeçalho binário.

  • ZDLE A TIPO F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 .Então, como faço para transmitir um byte de carga útil que corresponda ao valor de [ZDLE]?

18 58 (também conhecido como ZDLEE)

18 68 05 DE 02 18 D0

Esse é o rodapé do subquadro de dados.Os próximos 5 bytes são o CRC (o último byte é codificado em ZDLE)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top