2012-03-07 38 views
9

Tôi cần bao gồm các thói quen gửi tệp và gửi tệp cơ bản trong chương trình của mình và cần phải thông qua giao thức ZMODEM. Vấn đề là tôi đang gặp khó khăn trong việc hiểu thông số kỹ thuật.Hiểu giao thức ZMODEM

Để tham khảo, here is the specification.

Thông số kỹ thuật không xác định các hằng số khác nhau, vì vậy, đây là a header file from Google.

Dường như với tôi như có rất nhiều thứ quan trọng lại không xác định trong tài liệu đó:

  • Nó liên tục đề cập đến ZDLE mã hóa, nhưng nó là gì? Khi nào tôi sử dụng chính xác và khi nào tôi không sử dụng?
  • Sau khung dữ liệu ZFILE, siêu dữ liệu của tệp (tên tệp, ngày sửa đổi, kích thước, v.v.) được chuyển. Tiếp theo là khối ZCRCW và sau đó một khối có kiểu không được xác định theo spec. Khối ZCRCW bị cáo buộc chứa CRC 16 bit, nhưng thông số kỹ thuật không xác định dữ liệu CRC được tính.
  • Nó không xác định đa thức CRC mà nó sử dụng. Tôi phát hiện ra tình cờ rằng CRC32 poly là CRC32 tiêu chuẩn, nhưng tôi đã không có may mắn như vậy với nhiều CRC16. Nevermind, tôi tìm thấy nó thông qua thử và sai. Các CRC16 poly là 0x1021.

Tôi đã xem xung quanh để xem mã tham chiếu, nhưng tất cả những gì tôi có thể tìm thấy là các tệp C không thể đọc được, không có giấy tờ từ đầu những năm 90. Tôi cũng đã tìm thấy bộ tài liệu này từ MSDN, nhưng nó rất mơ hồ và mâu thuẫn với các thử nghiệm mà tôi đã chạy: http://msdn.microsoft.com/en-us/library/ms817878.aspx (bạn có thể cần phải xem thông qua Google's cache)

Để minh họa cho những khó khăn của tôi, đây là một ví dụ đơn giản. Tôi đã tạo một tệp văn bản thô trên máy chủ chứa "Hello world!" Và nó được gọi là helloworld.txt.

tôi bắt đầu chuyển từ máy chủ bằng lệnh sau:

sx --zmodem helloworld.txt 

này nhắc nhở các máy chủ để gửi khung ZRQINIT sau:

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

Ba vấn đề với điều này:

  • Các byte đệm (0x2A) có tùy ý không? Tại sao có hai ở đây, nhưng trong trường hợp khác chỉ có một, và đôi khi không có?
  • Thông số kỹ thuật không đề cập đến [CR] [LF] [XON] ở cuối, nhưng bài viết MSDN thực hiện. Tại sao nó lại ở đó?
  • Tại sao [LF] có bộ bit 0x80?

Sau đó, khách hàng cần gửi khung ZRINIT. Tôi nhận này từ bài viết MSDN:

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

Ngoài các [LF] 0x80 vấn đề cờ, tôi có thêm hai vấn đề:

  • Tại sao không được [XON] bao gồm thời gian này?
  • CRC có được tính trên dữ liệu nhị phân hoặc dữ liệu hex ASCII không? Nếu nó trên dữ liệu nhị phân tôi nhận được 0x197C, và nếu nó trên dữ liệu hex ASCII tôi nhận được 0xF775; không phải trong số này là những gì thực sự trong khung (0xBE50). (Giải quyết, nó theo bất kỳ chế độ bạn đang sử dụng.Nếu bạn đang ở trong BIN hoặc chế độ BIN32, đó là CRC của dữ liệu nhị phân.Nếu bạn đang ở chế độ hex ASCII, đó là CRC của những gì được đại diện bởi hex ASCII ký tự)

Các máy chủ đáp ứng với một khung ZFILE:.

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

OK. Điều này có ý nghĩa. Nếu tôi tính CRC32 của [04 00 00 00 00], tôi thực sự nhận được 0x33A251DD. Nhưng bây giờ chúng tôi không có bất kỳ [CR] [LF] [XON] ở cuối. Tại sao điều này?

Ngay sau khung này, máy chủ cũng gửi siêu dữ liệu của tập tin:

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

này thậm chí không có một tiêu đề, nó chỉ nhảy thẳng đến dữ liệu. OK, tôi có thể sống với điều đó. Tuy nhiên:

  • Chúng tôi có khung ZCRCW bí ẩn đầu tiên: [18 6B]. Khung này dài bao lâu? Dữ liệu CRC ở đâu và CRC16 hoặc CRC32? Nó không được định nghĩa ở bất kỳ đâu trong spec.
  • Bài viết MSDN chỉ định rằng [18 6B] phải được theo sau bởi [00], nhưng không phải.
  • Sau đó, chúng tôi có khung có loại không xác định: [18 50 D3 0F F1 11]. Đây có phải là một khung riêng biệt hay là một phần của ZCRCW?

Khách hàng cần phải đáp ứng với một khung ZRPOS, một lần nữa lấy từ bài viết MSDN:

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

vấn đề Tương tự như với khung ZRINIT: CRC là sai, các [LF] có bit 0x80 được đặt và không có [XON].

Các máy chủ đáp ứng với một khung ZDATA:

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

vấn đề Tương tự như ZFILE: CRC là tất cả tốt, nhưng đó là [CR] [LF] [XON]?

Sau này, máy chủ sẽ gửi tải trọng của tệp. Do đây là một ví dụ ngắn, nó phù hợp trong một khối (kích thước tối đa là 1024):

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

Từ những gì bài báo dường như đề cập, trọng tải đang trốn thoát với [ZDLE]. Vậy làm cách nào để truyền một byte tải trọng xảy ra để khớp với giá trị của [ZDLE]? Có giá trị nào khác như thế này không?

Các máy chủ kết thúc Những gọng kính:

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

Tôi hoàn toàn bị mất trên cái đầu tiên. Thứ hai có ý nghĩa nhiều như khung ZRINIT và ZDATA.

+0

Tôi đang làm việc trên chính xác cùng một điều cho chính xác cùng một lý do; Nếu bạn đã từng thực hiện công việc này và có mã nguồn, điều đó thật tuyệt vời ... –

+0

Điều này kết thúc như thế nào? Sau khi chi tiêu một vài ngày mã hóa để có được zmodem đáng tin cậy nhận được làm việc, tôi đã bỏ và chỉ vỏ ra để lrz. Làm việc trong một ngày. Đó là hư không gần như là sạch nhưng tôi đã không thực sự cảm thấy như dành nhiều thời gian hơn vào một giao thức đáng kính nhưng lỗi thời ... – bronson

+0

Ngoài ra, hãy cẩn thận! Tôi tìm thấy một vài thư viện mã zmodem khác trên mạng nhưng chúng hoàn toàn không đáng tin cậy! Có lẽ 5% các tập tin tôi đã thử đã kết thúc trong thất bại, và tôi thậm chí không cố gắng khai thác các trường hợp góc. Hãy chắc chắn rằng bạn sử dụng mã chiến đấu thử nghiệm, không phải dự án cuối tuần của một ai đó. – bronson

Trả lời

6

Bạn bè của tôi tự hỏi bạn có đang triển khai thời gian máy hay không.

Tôi không biết rằng tôi có thể trả lời tất cả các câu hỏi của bạn - Tôi chưa bao giờ thực sự đã phải thực hiện ZModem bản thân mình - nhưng đây là một vài câu trả lời:

Từ những gì bài báo dường như đề cập đến, tải trọng được thoát với [ZDLE]. Vậy làm cách nào để truyền một byte tải trọng xảy ra để khớp với giá trị của [ZDLE]? Có giá trị nào khác như thế này không?

này được giải quyết một cách rõ ràng trong tài liệu bạn có liên quan đến tại đầu câu hỏi của bạn, mà nói:

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. 

Nó liên tục đề cập đến ZDLE mã hóa, nhưng nó là gì? Khi nào chính xác tôi có sử dụng và khi nào tôi không sử dụng?

Trong các ngày cũ, một số "ký tự điều khiển" được sử dụng để điều khiển kênh truyền thông (do đó tên). Ví dụ: gửi các ký tự XON/XOFF có thể tạm dừng quá trình truyền. ZDLE được sử dụng để thoát khỏi các ký tự có thể có vấn đề. Theo spec, đây là những các ký tự được thoát theo mặc định:

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. 

Tôi đã nhìn xung quanh cho mã tham khảo, nhưng tất cả tôi có thể tìm được không đọc được, các file C không có giấy tờ từ đầu những năm 90 .

Điều này có bao gồm mã cho gói lrzsz không? Đây vẫn là có sẵn rộng rãi trên hầu hết các bản phân phối Linux (và đáng ngạc nhiên tiện dụng để truyền tệp qua kết nối ssh đã được thiết lập).

Có một số việc triển khai khác trên mạng, bao gồm nhiều trong phần mềm được liệt kê trên freecode, bao gồm qodem, syncterm, MBSE, và những người khác. Tôi tin rằng syncterm implementation được viết dưới dạng thư viện có thể hợp lý dễ dàng để sử dụng từ mã của riêng bạn (nhưng tôi không chắc chắn).

Bạn có thể tìm thấy mã bổ sung nếu bạn poke xung quanh các bộ sưu tập cũ hơn của phần mềm MS-DOS.

+0

Chúng tôi đang sử dụng một số bảng dev tại nơi làm việc chạy một hình ảnh Linux tùy chỉnh, và cách duy nhất để giao tiếp với họ là thông qua cổng UART (COM1). Chúng tôi thường xuyên phải chỉnh sửa các tệp trên bản dựng (sử dụng chương trình trình bao bọc mà tôi đang làm việc), thay vì biên dịch một hình ảnh mới mỗi lần, chúng tôi đã chọn lrzsz. Việc thoát ký tự bây giờ đã rõ ràng hơn một chút, nhưng tôi vẫn tự hỏi phạm vi là gì. Cảm ơn các liên kết mã, nó sẽ giúp tìm ra các sắc thái. Tôi sẽ đánh dấu đây là câu trả lời cho bây giờ. –

1

Tôi không thể đổ lỗi cho bạn. Hướng dẫn sử dụng không được tổ chức theo cách thức thân thiện với người dùng

Là byte đệm (0x2A) tùy ý?

Không, từ trang 14-15:

Một tiêu đề nhị phân bắt đầu bằng chuỗi ZPAD, ZDLE, ZBIN.

Tiêu đề hex bắt đầu bằng chuỗi ZPAD, ZPAD, ZDLE, ZHEX.

.

Thông số không đề cập đến [CR] [LF] [XON] ở cuối, nhưng bài viết MSDN thực hiện. Tại sao nó lại ở đó?

Trang 15

* * ZDLE B TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON . Tại sao [LF] có bộ bit 0x80?

Không chắc chắn. Từ thuật ngữ Tera, tôi có cả hai ký tự điều khiển XORed với 0x80 (8D 8A 11)

Chúng ta có khung ZCRCW bí ẩn đầu tiên: [18 6B]. Khung này dài bao lâu? Dữ liệu CRC ở đâu và CRC16 hoặc CRC32? Nó không được định nghĩa ở bất kỳ đâu trong spec.

ZCRCW không phải là tiêu đề hoặc loại khung, nó giống như chân trang cho người nhận biết điều gì sẽ xảy ra tiếp theo. Trong trường hợp này, nó là chân của lớp con dữ liệu chứa tên tệp. Nó sẽ là một tổng kiểm tra 32 bit bởi vì bạn đang sử dụng tiêu đề nhị phân kiểu "C".

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

.

Sau đó, chúng tôi có khung có loại không xác định: [18 50 D3 0F F1 11]. Đây có phải là một khung riêng biệt hay là một phần của ZCRCW?

Đó là CRC cho gói dữ liệu ZCRCW. Đó là 5 byte bởi vì cái đầu tiên là 0x10, một ký tự điều khiển cần được thoát ZDLE. Tôi không chắc 0x11 là gì.

và không có [XON].

XON chỉ dành cho tiêu đề Hex. Bạn không sử dụng nó cho một tiêu đề nhị phân.

  • ZDLE Một LOẠI F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 . Vậy làm cách nào để truyền một byte tải trọng xảy ra để khớp với giá trị của [ZDLE]?

18 58 (AKA ZDLEE)

18 68 05 02 18 DE D0

Đó là chân của các khung phụ dữ liệu.5 byte tiếp theo là CRC (byte cuối cùng được mã hóa ZDLE)

Các vấn đề liên quan