質問
基本的なファイル送信ルーチンとファイル受信ルーチンをプログラムに組み込む必要があり、ZMODEM プロトコルを使用する必要があります。問題は、仕様を理解するのが難しいことです。
参考のため、 ここに仕様があります.
仕様ではさまざまな定数が定義されていないため、次のとおりです。 Google からのヘッダー ファイル.
この文書には未定義のままの重要なことがたくさんあるように思えます。
- 常に ZDLE エンコーディングを参照していますが、 それは何ですか? 正確にいつ使用し、いつ使用しないのですか?
- ZFILE データ フレームの後に、ファイルのメタデータ (ファイル名、変更日、サイズなど) が転送されます。これに ZCRCW ブロックが続き、仕様に従ってタイプが定義されていないブロックが続きます。ZCRCW ブロックには 16 ビット CRC が含まれていると言われていますが、仕様ではどのデータに基づいて CRC が計算されるかが定義されていません。
使用する CRC 多項式は定義されません。CRC32 ポリが標準の CRC32 であることを偶然知りましたが、CRC16 ポリではそのような運がありませんでした。気にしないでください、私は試行錯誤して見つけました。CRC16 ポリは 0x1021 です。
リファレンス コードを探し回りましたが、見つかったのは 90 年代初頭の、文書化されていない判読不能な C ファイルだけでした。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.Š.
これには次の 3 つの問題があります。
- パディングバイト (0x2A) は任意ですか?なぜここには 2 つあるのに、他の例では 1 つだけ、あるいはまったくない場合があるのでしょうか?
- 仕様には最後に [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 フラグの問題に加えて、さらに 2 つの問題があります。
- 今回はなぜ[XON]が入っていないのでしょうか?
CRC はバイナリ データまたは ASCII 16 進データで計算されますか?バイナリ データの場合は 0x197C が返され、ASCII 16 進データの場合は 0xF775 が返されます。これらはどちらも実際のフレーム (0xBE50) 内にあるものではありません。(解決済み;使用しているモードに従います。BIN または BIN32 モードの場合、それはバイナリ データの CRC です。ASCII 16 進モードを使用している場合、これは ASCII 16 進文字で表されるものの CRC です。)
サーバーは ZFILE フレームで応答します。
2A 18 43 04 00 00 00 00 DD 51 A2 33 *.C.....ÝQ¢3
わかりました。これは理にかなっています。[04 00 00 00 00] の CRC32 を計算すると、確かに 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 の一部ですか?
クライアントは、MSDN の記事から引用した ZRPOS フレームで応答する必要があります。
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] はどこにありますか?
この後、サーバーはファイルのペイロードを送信します。これは短い例なので、1 つのブロックに収まります (最大サイズは 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
最初のものでは完全に迷っています。2 番目のフレームは、ZRINIT フレームや ZDATA フレームと同じくらい意味があります。
解決
私の相棒は、あなたがタイムマシンを実装しているかどうか疑問に思います。
私はあなたのすべての質問に答えることができることを知りません - 私は実際にZmodemを自分で実装する必要がありませんでした - しかし、ここにいくつかの答えがあります:
記事が言及しているように見えることから、ペイロードは[zdle]で逃げられます。では、[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文字を送信すると、送信が一時停止する場合があります。Zdleは、問題がある可能性のあるキャラクターを逃れるために使用されます。仕様によると、これらはデフォルトで脱出される文字です。
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.
参照コードを探しましたが、見つけることができるのは、90年代前半の読みにくい文書化されていないCファイルだけです。
これには、 るず パッケージ?これは、ほとんどのLinux分布でまだ広く利用可能です(そして、確立されたSSH接続を介してファイルを送信するのに驚くほど便利です)。
上にリストされているソフトウェアのいくつかを含む、他にも多くの実装があります フリーコード, 、 含む コーデム, 同期期間, MBSE, 、 その他。私は信じます 同期の実装 あなた自身のコードから合理的に使いやすいかもしれないライブラリとして書かれています(ただし、私は確かではありません)。
MS-DOSソフトウェアの古いコレクションを突く場合、追加のコードを見つけることができます。
他のヒント
あなたを責めることはできません。ユーザーマニュアルはユーザーフレンドリーに構成されていません
パディングバイト (0x2A) は任意ですか?
いいえ、14、15 ページから:
バイナリ ヘッダーは、ZPAD、ZDLE、ZBIN のシーケンスで始まります。
16 進ヘッダーは、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 用語から、両方の制御文字を 0x80 (8D 8A 11) と XOR 演算しました。
最初の謎の ZCRCW フレームがあります。【18 6B】。このフレームの長さはどれくらいですか?CRC データはどこにありますか? CRC16 または CRC32 ですか?仕様のどこにも定義されていません。
ZCRCW はヘッダーやフレーム タイプではなく、受信者に次に何を期待するかを伝えるフッターに似ています。この場合、これはファイル名を含むデータ サブパケットのフッターです。「C」タイプのバイナリヘッダーを使用しているため、これは 32 ビットのチェックサムになります。
- ズドル C タイプ F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CRC-3 CRC-4
.
次に、未定義のタイプのフレームがあります。[18 50 D3 0F F1 11]。これは別のフレームですか、それとも ZCRCW の一部ですか?
これは、ZCRCW データ サブパケットの CRC です。最初のバイトは 0x10 (ZDLE エスケープする必要がある制御文字) であるため、これは 5 バイトです。0x11が何なのか分かりません。
[XON] はありません。
XON は 16 進ヘッダー専用です。バイナリヘッダーには使用しません。
- Zdle A型F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2。では、偶然 [ZDLE] の値と一致したペイロード バイトを送信するにはどうすればよいでしょうか?
18 58 (別名ZDLEE)
18 68 05 DE 02 18 D0
それはデータ サブフレームのフッターです。次の 5 バイトは CRC です (最後のバイトは ZDLE でエンコードされます)