2012-03-07 269 views
9

我需要在我的程序中包含基本的文件發送和文件接收例程,它需要通過ZMODEM協議。問題是我無法理解規範。瞭解ZMODEM協議

僅供參考,here is the specification

該規範沒有定義各種常量,所以這裏是a header file from Google

在我看來,像有很多重要的事情在該文件中未定義:

  • ,它始終是指ZDLE編碼,但是什麼呢?什麼時候使用它,何時不使用它?
  • 在ZFILE數據框之後,文件的元數據(文件名,修改日期,大小等)被傳輸。接下來是ZCRCW塊,然後是根據規範未定義類型的塊。據稱ZCRCW模塊包含一個16位CRC,但該規範沒有定義CRC計算的數據。
  • 它沒有定義它使用的CRC多項式。我偶然發現CRC32 poly是標準的CRC32,但我沒有CRC16 poly的這種運氣。沒關係,我通過反覆試驗找到了它。 CRC16 poly是0x1021。

我查找過參考代碼,但是我能找到的所有文件都是從90年代初期以來無法讀取的,未公開的C文件。我還發現這一套從MSDN文檔,但它是痛苦的模糊和矛盾的,我已經運行的測試:http://msdn.microsoft.com/en-us/library/ms817878.aspx(您可能需要查看通過Google's cache

爲了說明我的困難,這裏是一個簡單的例子。我在包含「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十六進制模式,則表示ASCII十六進制字符)

服務器用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的一部分?

客戶需要用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幀一樣有意義。

+0

由於完全相同的原因,我正在處理完全相同的事情;如果你曾經做過這個工作,並且有源代碼,那將會很棒...... – 2013-05-27 10:45:50

+0

這是怎麼回事?花了幾天編碼來獲得可靠的zmodem接收工作後,我放棄了,直接去lrz。一天工作。它遠沒有那麼幹淨,但我真的不想花費更多的時間在一個古老而過時的協議上...... – bronson 2016-11-01 22:50:44

+0

另外,要小心!我發現了一些其他的zmodem代碼庫,但它們都是完全不可靠的!我試過的文件中大概有5%以失敗告終,我甚至沒有試圖利用角落案例。確保你使用經過測試的代碼,而不是某人的週末項目。 – bronson 2016-11-01 22:53:34

回答

6

我的好友不知道你是否正在執行一個時間 機器。

我不知道我可以回答你所有的問題 - 我從來 實際上不得不實施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 [email protected] The receiver ignores 
021, 0221, 023, and 0223 characters in the data stream. 

我環顧四周,以供參考代碼,但我能看到的是 不可讀,無證C來自90年代初的文件。

這是否包含lrzsz包的代碼?這仍然是大多數Linux發行版中廣泛可用的 (並且在通過建立的ssh連接傳輸文件方面令人驚訝地得心應手的 )。

還有一些其他的實現在那裏,其中包括軟件 幾個上freecode上市,包括qodemsynctermMBSE,等等。我相信syncterm implementation被寫爲庫,可能合理容易 使用從您自己的代碼(但我不確定)。

如果你捅的 MS-DOS軟件圍繞舊的集合您可能會發現更多的代碼。

+0

我們在工作中使用一些運行定製Linux映像的開發板,唯一與它們通信的方式是通過UART(COM1)端口。我們經常需要編輯構建文件(使用我正在處理的包裝程序),所以不是每次都編譯一個新的映像,而是選擇lrzsz。字符轉義現在有點清晰,但我仍然在想,範圍是什麼。感謝代碼鏈接,它應該幫助找出這些細微差別。我會將此標記爲現在的答案。 – 2012-03-14 21:49:36

1

我不怪你。用戶手冊沒有以用戶友好的方式組織

是否填充字節(0x2A)是任意的?

否,從14,15頁:

甲二進制標頭開始的順序ZPAD,ZDLE,ZBIN。

十六進制標頭開始的順序ZPAD,ZPAD,ZDLE,ZHEX。

規範在最後沒有提到[CR] [LF] [XON],但是MSDN文章沒有提到。爲什麼在那裏?

第15頁

* * ZDLE B型F3/P0 F2/F1 P1/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」型二進制頭文件。

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

然後我們有一個未定義類型的幀:[18 50 D3 0F F1 11]。這是一個單獨的框架,還是它是ZCRCW的一部分?

這就是ZCRCW數據子包的CRC。這是5字節,因爲第一個字符是0x10,一個需要被ZDLE轉義的控制字符。我不確定0x11是什麼。

而且也沒有[XON。

XON只是爲六角頭。你不使用它作爲二進制頭文件。

  • ZDLE甲TYPE F3/P0 F2/F1 P1/P2 F0/P3 CRC-1 CRC-2 。 那麼,如何傳遞恰好匹配[ZDLE]值的有效載荷字節?

18 58(AKA ZDLEE)

18 68 05 DE 02 18 D0

這就是數據子幀的頁腳。接下來的5個字節是CRC(最後一個字節是ZDLE編碼)