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.
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 ... –
Đ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
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