当前位置: 首页 > news >正文

Zmodem

Zmodem

Zmodem是一种文件传输协议,它试图最大化带宽并最小化传输时间。它是一种单向协议;即返回信道仅传输控制信息;没有数据。任何一方都可以发起转移;但是下载站点可以通过自动启动下载软件来响应初始化帧。

正在进行的zmodem文件传输示意图如下:

	  |----------<< back channel <<-------------|
------+-------				 			--------+------
|  Sender  | 							|  Receiver  |
| (upload) | 							| (download) |
--------------					 		--------+------|---------->> data channel >>-------------|

所有zmodem事务都是使用框架完成的。一个帧由一个报头和一个或多个数据子包组成。典型的(简单的)zmodem文件传输如下:

image-20250609145823781

zmodem持续传输数据,除非接收器中断发送器请求重新传输乱码数据。zmodem实际上将整个文件用作窗口。

FRAMING 帧定界

ZMODEM 帧有 2 种类型:

​ 1.十六进制(HEX)帧,仅包含 US-ASCII 字符

​ 2.二进制(BIN16 或 BIN32)帧,包含几乎所有可能的八位字节值

十六进制帧

<frame header> [CR] LF [XON]

HEX 帧以 ASCII 换行字符终止。某些 ZMODEM 实现会将 HEX 帧终止的换行字符的高位设置(0x8A,即带有偶校验位的 ASCII-LF)。此外,对于某些 HEX 帧类型,帧终止符后可能会跟随一个 XON(0x11)字符(在所谓的“软件流控”中代表“传输开启”)。

二进制帧

<frame header> [[<* data subpacket> [...]] <ZCRCW | ZCRCE data subpacket>]

Binary frames may contain zero or more data subpackets (depending on the frame type). The final subpacket of a binary data frame will be of type ZCRCW or ZCRCE.
二进制帧可以包含零个或多个数据子包(具体数量取决于帧类型)。二进制数据帧的最后一个子包类型将是 ZCRCW 或 ZCRCE。

帧头

<frame encoding> <frame type> <frame info> <checksum>

帧编码(单字节):
帧编码有时也被称为“帧样式”。

样式 AKA Value 值 Frame Contents 帧内容 Checksum 校验和
HEX ZHEX ASCII 'B' 仅限十六进制/US-ASCII 字符 16-bit CRC 16 位 CRC
BIN16 ZBIN ASCII 'A' ASCII 'A '' Binary 二进制 16-bit CRC 16 位 CRC
BIN32 ZBIN32 ASCII 'C' Binary 二进制 32-bit CRC 32 位 CRC

Notes: 注释:

  • “接收器”发送的所有帧必须使用十六进制编码。

Frame Type (single byte):
帧类型(单字节):

Type 类型 Value 值 TX发送 RX接收 Info 信息 Data Subpkt 数据子包 Notes 注释
ZRQINIT 0x00 Y - caps 功能 - Request ZRINIT from the receiver 请求接收器发送 ZRINIT
ZRINIT 0x01 - Y caps 大写字母 - Receiver Initialized 接收器已初始化
ZSINIT 0x02 Y - flags 标志位 Attn sequence 提示序列 Sender Initialized 发送方初始化
ZACK 0x03 Y Y offset 偏移量 - Positive Acknowledgment 正确确认
ZFILE 0x04 Y - options 选项 File metadata 文件元数据 File information (name/len/date) 文件信息(名称/长度/日期)
ZSKIP 0x05 - Y - Skip (don't send) this file 跳过(不发送)此文件
ZNAK 0x06 Y Y - Negative Acknowledgment 否定确认
ZABORT 0x07 - Y - Terminate batch file transfer 终止批文件传输
ZFIN 0x08 Y - - Terminate transfer session 终止传输会话
ZRPOS 0x09 - Y offset 偏移量 - Reposition the send offset 重新定位发送偏移量
ZDATA 0x0A Y - offset 偏移量 File contents 文件内容 One or more data subpackets follow 一个或多个数据子数据包跟随
ZEOF 0x0B Y - offset 偏移量 - End of file reached 文件结束
ZFERROR 0x0C - Y - File I/O error 文件 I/O 错误
ZCRC 0x0D Y Y CRC-32 - File CRC request/response 文件 CRC 请求/响应
ZFREECNT 0x11 Y - f-space - Request free disk space 请求空闲磁盘空间

帧信息:最多 15 字节(但通常为 4)的特定于帧类型的帧信息。

注意,后续关于 16 字节可能帧头数据的声明包括帧类型字节。

帧头完整性:帧类型和帧信息使用 16 位或 32 位 CRC(由帧编码决定)进行完整性保护。

数据子包

<data> ZDLE <subpacket type> <crc>

ZDLE 是 ZMODEM 的数据链路转义字符( ^X ,ASCII 24)。

数据子包长度

  • 数据子包可以包含最多 1024 字节的数据(特殊的八位值会被转换并使用 ZDLE 转义)
  • 数据子包长度有时也被称为传输的“块大小”
  • 数据子包长度可以在文件传输过程中由发送方动态调整,例如响应接收方报告的错误
  • 某些 ZMODEM 实现(例如“ZedZap”)支持高达 8K(8192 字节)的数据子包长度

数据子包类型

数据子包类型用单个字节编码。

Type ZACK/ZRPOS expected ZACK/ZRPOS 期待 End-of-Frame Meaning Notes
ZCRCW Yes (synchronous) 是(同步) Yes Wait or Write “ZCRCW 数据子包在发送下一个帧之前需要响应...以允许接收器在发送更多数据前写入其缓冲区”
ZCRCE Only errors 仅错误 Yes End “如果在数据帧中遇到文件末尾,该帧将使用一个不引发响应的 ZCRCE 数据子包关闭,除非发生错误”
ZCRCQ Yes (asynchronous) 是(异步) No Query “如果接收器没有用[ZRINIT] CANFDX 位指示全双工能力,则不会使用 ZCRCQ 子包”
ZCRCG Only errors No Go “ZCRCG 子包在未检测到错误时不会引发响应”

链路转义编码

ZMODEM 转义编码是一种用于文件传输协议中的特殊编码方式,主要用于在数据传输过程中避免控制字符的冲突,确保传输的可靠性。

在ZMODEM或其他串行通信协议中,冲突的发生主要是因为数据传输过程中需要区分两类字符:

  1. 协议控制字符(如帧头、确认信号、终止符等);
  2. 普通数据字符(文件的实际内容)。

如果文件数据中恰好包含与控制字符相同的字节值,接收端可能会误将其解释为协议指令,导致传输错误.

ZMODEM通过转义编码解决上述冲突:

  • 转义冲突字符
    将数据中的控制字符(如0x18)替换为转义序列(如0x18 0x58),接收端反向解码即可还原。

链接转义编码确实会增加一些开销。最坏的情况下,一个完全由转义字符组成的文件会产生 50%的开销。

ZDLE 字符是特殊的。ZDLE 代表某种控制序列。如果二进制数据中出现 ZDLE 字符,它会被前缀 ZDLE,然后作为 ZDLEE 发送。

连续收到五个 CAN 字符将中止 zmodem 会话。为确保安全,会发送八个 CAN 字符。

接收程序将任何 ZDLE 后跟一个第 6 位设为 1 且第 5 位设为 0 的字节(大写字母,奇偶校验)解码为等效的控制字符,通过反转第 6 位。这允许发送程序逃避通信媒介无法发送的任何控制字符。此外,接收程序还识别需要转义的字符 0x7f 和 0xff。

zmodem 软件转义 ZDLE(0x18)、0x10、0x90、0x11、0x91、0x13 和 0x93。

如果 0x40 或 0xc0(@)作为前缀,0x0d 和 0x8d 也会被转义,以保护 Telenet 命令转义 CR-@-CR。接收程序会忽略数据流中的 0x11、0x91、0x13 和 0x93 字符。

HEADERS 头部

所有 zmodem 帧都以头部开始,该头部可以以二进制或十六进制形式发送。无论哪种形式的头部都包含相同原始信息:

- 一个类型字节

-四个字节的数据,表示标志和/或根据帧类型变换的数值量

最大头部信息长度为16字节

           M         LFTYPE  F3 F2 F1 F0   (flags frame)
           L         MFTYPE  P0 P1 P2 P3   (numeric frame)

注意陷阱;标志和数字的索引顺序是相反的!

16 BIT CRC BINARY HEADER 16 位 CRC 二进制头部

发送程序向接收程序发送二进制头部。二进制头部中的所有字节都经过 ZDLE 编码。

二进制头部以序列 ZPAD、ZDLE、ZBIN 开始。

根据帧类型,将跟随 0 个或多个带有 16 位 CRC 的二进制数据子数据包。

* ZDLE A TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2

32 位 CRC 二进制头部

一个“32 位 CRC”二进制头部与二进制头部类似,不同之处在于 ZBIN (A) 字符被替换为 ZBIN32 (C) 字符,并发送四个 CRC 字符。

根据帧类型,将跟随 0 个或多个带有 32 位 CRC 的二进制数据子数据包。

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

十六进制头部

接收器以十六进制头发送响应。当发送器不跟随着二进制数据子包时,也使用十六进制头。

十六进制编码保护反向信道免受随机控制字符的影响。十六进制头接收例程忽略奇偶校验。

接收程序使用十六进制头允许在检测到错误时使用控制字符来中断发送器。十六进制头可以在任何方便的地方代替二进制头使用。如果数据包跟随一个十六进制头,它将使用 CRC-16 进行保护。

十六进制头以序列 ZPAD、ZPAD、ZDLE、ZHEX 开始。额外的 ZPAD 字符允许发送程序检测异步头(表示错误状态),然后使用非特定错误的例程获取剩余的头信息。

*类型字节、四个位置/标志字节及其 16 位 CRC 值使用字符集 01234567890abcdef 以十六进制形式发送。不允许使用大写十六进制数字。由于这种十六进制编码形式可以检测多种错误模式,特别是缺失字符,因此未定义带有 32 位 CRC 的十六进制标题。

使用十六进制标题时发送回车和换行符。接收例程期望至少看到一个这样的字符,如果第一个是 CR,则期望看到两个。

除 ZACK 和 ZFIN 外,所有十六进制数据包都会附加一个 XON 字符。XON 释放发送者免受线路噪声产生的虚假 XOFF 流控字符的影响。ZACK 标题后不发送 XON 以保护流式情况下的流控。ZFIN 标题后不发送 XON 以允许正确的会话清理。

根据帧类型,将跟随 0 个或多个数据子包。

* * ZDLE B TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON

(TYPE、F3...F0、CRC-1 和 CRC-2 均以两个十六进制数字发送。)

二进制数据子包

二进制数据子包紧随相关的二进制头包之后。一个二进制数据包包含 0 到 1024 个字节的数据。推荐长度值在 2400 bps 以下为 256 字节,2400 bps 时为 512 字节,4800 bps 以上或当数据链路已知相对无错误时为 1024 字节。

二进制数据子包不使用填充。数据字节使用 ZDLE 编码后传输。随后发送一个 ZDLE 和一个帧结束符,接着是两个或四个 ZDLE 编码的 CRC 字节。CRC 会累积数据字节和帧结束符。

协议事务概述

zmodem 的时序由接收端驱动。发送端不应超时,除非在一段时间内(比如一分钟)未收到任何头部信息时,需要中止程序。

会话启动

要启动 zmodem 文件传输会话,发送程序被调用,并传入所需文件名和选项。

然后发送端可以发送 ZRQINIT 头部。ZRQINIT 头部会促使已启动的接收程序立即发送其 ZRINIT 头部。

发送程序等待接收程序发出命令以开始文件传输。

如果数据损坏,发送程序可以重复发送接收邀请多次,直到会话开始。

当 zmodem 接收程序启动时,它会立即发送 ZRINIT 头部给发送程序,以启动 zmodem 文件传输,或发送 ZCHALLENGE 头部以验证发送程序。

只要接收程序收到ZRQINIT头部,它就会发送ZRINIT头部。如果发送程序接收到ZCHALLENGE 头部,它会在应答的ZACK头部中将数据放在ZP0...ZP3中。

如果接收程序收到 ZRINIT 头部,这是一个回声,表示发送程序未运行。

最终发送程序正确接收了 ZRINIT 头部。

(发送者随后可以发送一个可选的 ZSINIT 帧,用于定义接收程序的注意序列,或指定完整的控制字符转义。如果接收者指定了相同或更高级别的转义,则无需发送 ZSINIT 帧,除非需要注意序列。

如果 ZSINIT 头部指定了 ESCCTL 或 ESC8,则使用 HEX 头部,接收者在读取后续的数据子包之前会激活指定的 ESC 模式。

接收者响应发送一个 ZACK 头部。)

文件传输

发送程序随后发送一个包含zmodem转换、管理和传输选项的ZFILE头部,接着发送一个包含文件名、文件长度和修改日期的 ZCRCW 数据子包。

接收程序可以根据指定的传输选项、其文件系统的当前状态或本地的安全要求,检查发送程序提供的文件名、长度和日期信息。

接收程序可以响应ZSKIP头部,使发送程序继续处理批量中的下一个文件。(若存在)

接收程序发送ZRPOS头部,启动从ZOPRS头部指定的文件偏移量开始传输文件数据。

接收方可以从文件的更低位置开始传输。这允许在载波丢失或系统崩溃中断的文件传输在下一次连接时完成,而无需重新传输整个文件。如果从变得迟缓的分时系统下载文件,可以中断传输并在稍后继续,而不会丢失数据。

发送方发送一个带有文件位置的 ZDATA 二进制头部,随后发送一个或多个数据子包。

接收器将 ZDATA 头中的文件位置与成功接收的字符数进行比较。如果两者不一致,将生成 ZRPOS 错误响应,迫使发送器到达文件中的正确位置。(如果使用 ZMSPARS 选项,接收器将改为跳转到 ZDATA 头中指定的位置)。

一个长度为零的数据帧可以用作空闲子包,以防止接收器在没有立即可用数据的情况下超时。

发送器发送一个 ZEOF 头部,文件结束偏移量等于文件中的字符数。接收器将这个数字与接收到的字符数进行比较。如果接收器已经接收了所有文件内容,它会关闭文件。如果文件关闭是成功的,接收器会响应 ZRINIT。如果接收器没有接收完所有文件字节,它会忽略 ZEOF,因为一个新的 ZDATA 正在到来。如果接收器无法正确关闭文件,会发送 ZFERR 头部。

在所有文件处理完毕后,任何进一步的协议错误都不应阻止发送程序以成功状态返回。

会话清理

发送方使用 ZFIN 头部关闭会话。接收方用其自身的 ZFIN 头部进行确认。

当发送方收到确认头部时,它会发送两个字符“OO”(Over and Out)然后退出。接收方会短暂等待“O”字符,无论是否收到,都会退出。

帧类型

ZRQINIT

由发送程序发送,以触发接收程序发送其 ZRINIT 头部。如果初次未获得响应,发送程序可以重复发送接收邀请。

如果程序正在尝试发送命令,ZF0包含ZCOMMAND,否则为0。

ZRINIT

由接收程序发送。ZF0 和 ZF1 包含接收器功能标志的按位或:

标志位 含义
CANCRY 接收器可以解密
CANFDX 接收器可以发送和接收真正的全双工
CANOVIO 接收器可以在磁盘 I/O 期间接收数据
CANBRK 接收器可以发送一个中断信号
CANCRY 接收器可以解密
CANLZW 接收器可以解压缩
CANFC32 接收器可以使用 32 位帧校验
ESCCTL 接收器期望控制字符被转义
ESC8 接收器期望第 8 位被转义

ZPO0和ZP1包含接收器缓冲区的大小(以字节为单位),如果允许连续I/O,则为0

ZSINIT

发送者发送标志,然后是一个以 ZCRCW 结尾的二进制数据子分组。

ZACK

对ZSINIT帧的确认、ZCHALLENGE头部、ZCRCQ或ZCRCW数据子包。ZP0至ZP1包含文件偏移量。对ZCHALLENGE的响应包含与ZCHALLENGE头部接收到的相同32位数字。

ZFILE

此帧表示文件传输尝试的开始。ZF0、ZF1 和 ZF2 可能包含选项。这些字节中的每个字节值为 0 表示无特殊处理。

ZF1: 管理选项

如果接收器不识别管理选项,文件应正常传输。

ZMNEWL 如果目标文件不存在,则传输文件。否则,如果源文件更新或更长,则覆盖目标文件传输文件。
ZMCRC 比较源文件和目标文件。如果文件长度或文件多项式不同,则传输文件。
ZMAPND 将源文件内容追加到现有目标文件的末尾(如果存在)。
ZMCLOB 替换现有目标文件(如果存在)。
ZMDIFF 如果目标文件不存在,则传输文件。否则,如果文件具有
ZMPROT 保护目标文件,仅在目标文件不存在时才传输文件。
ZMNEW 如果目标文件不存在,则传输文件。否则,如果源文件更新,则覆盖目标文件传输。

ZF2: 传输选项

如果接收器未实现特定的传输选项,文件将未经转换地复制以供后续处理。最好不要使用这些。参见 readme

ZTLZW 传输的数据将与在具有 VAX 字节顺序的计算机上运行的 compress 4.0 产生的数据完全相同,使用 12 位编码。
ZTCRYPT 加密。一个初始的空字符终止的字符串标识密钥。
ZTRLE 行程长度编码。

随后是一个 ZCRCW 数据子包,包含文件名、文件长度、修改日期以及后一章中描述的其他信息。

ZF3: 扩展选项

扩展选项是按位编码的。

ZTSPARS 对稀疏文件的特殊处理,或发送者管理的选择性重传。每个文件片段都作为单独的帧传输,这些帧不一定连续。发送者应在每个片段末尾添加 ZCRCW 数据子包,并处理预期的 ZACK 以确保数据没有丢失。ZTSPARS 不能与 ZCNL 一起使用。

ZSKIP

由接收器在响应 ZFILE 时发送,使发送器跳到下一个文件。

ZNAK

表示最后一个标题已损坏。(另见 ZRPOS)。

ZABORT

由接收器发送,用于在用户请求时终止批量文件传输。发送者会响应 ZFIN 序列(服务器模式下为 ZCOMPL)。

ZFIN

由发送程序发送以终止 zmodem 会话。接收方用其自身的 ZFIN 响应。

ZRPOS

由接收器发送,强制文件传输在 ZP0...ZP3 中指定的文件偏移处恢复。

ZDATA

ZP0...ZP3 包含文件偏移量。一个或多个数据子数据包随后发送

ZEOF

发送器报告文件结束。ZP0...ZP3 包含结束的文件偏移量。

ZFERR

读取或写入文件时出错,协议等同于 ZABORT。

ZCRC

请求(接收者)和响应(发送者)用于文件多项式。ZP0...ZP3 包含文件多项式。

ZCHALLENGE

请求发送者在 ZP0...ZP3 中回显一个随机数,通过 ZACK 帧发送。由接收程序发送给发送程序,以验证其是否连接到操作程序,且未被虚假数据或木马消息激活。这是有史以来最容易被攻破的安全系统。不要依赖它,最好完全不要使用或实现它。围绕从开始下载构建安全措施,并禁止明确路径名来建立你的安全措施。

ZCOMPL

请求现已完成。

ZCAN

这是一个对会话中止序列的伪帧类型。

ZFREECNT

发送程序请求一个 ZACK 帧,其中包含 ZP0...ZP3,显示当前文件系统中的空闲字节数。0 值表示无限量的空闲空间。

ZFILE 帧文件信息子包

zmodem 使用 ZFILE 帧数据发送相同的文件信息

路径名(文件名)字段是必填的。路径名之后的每个字段都是可选的,并且与前面的字段用空格分隔。字段不能被省略。可选字段的使用(根据定义)是可选的,由接收者决定。

PATHNAME

路径名(通常指文件名)作为以空字符终止的 ASCII 字符串发送。路径名中不包含空格。

文件名注意事项

  • 文件名应该转换为小写,除非发送系统支持大小写文件名。这是为了方便使用(如 Unix)等在存储文件名时区分大小写的系统的用户。
  • 接收者应该兼容大小写文件名。
  • 在跨不同操作系统传输文件时,文件名必须同时被发送方和接收方操作系统所接受。如果不是这样,就需要对文件名进行转换使其可接受。如果转换不成功,接收程序可能会创建一个新的文件名。
  • 如果包含目录,它们由/分隔;即 subdir/foo 是可接受的, subdir\foo 则不可接受。

长度

长度字段以十进制字符串形式存储,表示文件中数据字节数。

zmodem 接收器仅将文件长度作为估计值使用。它可用于显示传输时间的估计值,并可与可用磁盘空间进行比较。实际接收到的文件长度由数据传输决定。文件在传输开始后可能会增长,所有数据都将被发送。

修改日期

最后修改日期以八进制数的形式发送,表示从 1970 年 1 月 1 日世界协调时间(GMT)起经过的秒数,即文件内容最后一次更改的时间。日期为 0 表示修改日期未知,应保留文件接收时的日期。

选择这种标准格式是为了消除因跨时区传输而产生的歧义。

文件模式

文件模式以八进制字符串的形式存储。除非文件来自 Unix 系统,否则文件模式设置为 0。

序列号

将此字段设置为 0。

剩余文件数量

此字段以十进制数编码,包括当前文件。此字段为估计值,不允许错误的值导致数据丢失。

剩余字节数

此字段以十进制数编码,包括当前文件。此字段为估计值,不允许错误的值导致数据丢失。

文件类型

将此字段设置为 0。

文件信息以空字符终止。如果只发送路径名,路径名将以两个空字符终止。文件信息子包的长度(包括末尾的空字符)不得超过 1024 字节;典型长度小于 64 字节。

CONSTANTS 常量

ASCII

SOH		0x01
STX		0x02
EOT		0x04
ENQ		0x05
ACK		0x06
LF		0x0a
CR		0x0d
XON		0x11
XOFF	0x13
NAK		0x15
CAN		0x18

ZMODEM

ZPAD		0x2a	/* pad character; begins frames */
ZDLE		0x18	/* ctrl-x zmodem escape */
ZDLEE		0x58	/* escaped ZDLE */	ZBIN		0x41	/* binary frame indicator (CRC16) */
ZHEX		0x42	/* hex frame indicator */
ZBIN32	    0x43	/* binary frame indicator (CRC32) */
ZBINR32	    0x44	/* run length encoded binary frame (CRC32) */ZVBIN		0x61	/* binary frame indicator (CRC16) */
ZVHEX		0x62	/* hex frame indicator */
ZVBIN32		0x63	/* binary frame indicator (CRC32) */
ZVBINR32	0x64	/* run length encoded binary frame (CRC32) */ZRESC		0x7e	/* run length encoding flag / escape character */

FRAME TYPES 帧类型

ZRQINIT	    0x00	/* request receive init (s->r) */
ZRINIT	    0x01	/* receive init (r->s) */
ZSINIT	    0x02	/* send init sequence (optional) (s->r) */
ZACK		0x03	/* ack to ZRQINIT ZRINIT or ZSINIT (s<->r) */
ZFILE		0x04	/* file name (s->r) */
ZSKIP		0x05	/* skip this file (r->s) */
ZNAK		0x06	/* last packet was corrupted (?) */
ZABORT	    0x07	/* abort batch transfers (?) */
ZFIN		0x08	/* finish session (s<->r) */
ZRPOS		0x09	/* resume data transmission here (r->s) */
ZDATA		0x0a	/* data packet(s) follow (s->r) */
ZEOF		0x0b	/* end of file reached (s->r) */
ZFERR		0x0c	/* fatal read or write error detected (?) */
ZCRC		0x0d	/* request for file CRC and response (?) */
ZCHALLENGE	0x0e	/* security challenge (r->s) */
ZCOMPL	    0x0f	/* request is complete (?) */	
ZCAN		0x10	/* pseudo frame; other end cancelled session with 5* CAN */
ZFREECNT	0x11	/* request free bytes on file system (s->r) */
ZCOMMAND	0x12	/* issue command (s->r) */
ZSTDERR		0x13	/* output data to stderr (??) */

ZDLE SEQUENCES ZDLE 序列

ZCRCE		0x68	/* CRC next, frame ends, header packet follows */
ZCRCG		0x69	/* CRC next, frame continues nonstop */
ZCRCQ		0x6a	/* CRC next, frame continuous, ZACK expected */
ZCRCW		0x6b	/* CRC next, ZACK expected, end of frame */
ZRUB0		0x6c	/* translate to rubout 0x7f */
ZRUB1		0x6d	/* translate to rubout 0xff */

RECEIVER CAPABILITY FLAGS 接收器功能标志

CANFDX		0x01	/* Rx can send and receive true full duplex */
CANOVIO		0x02	/* Rx can receive data during disk I/O */
CANBRK		0x04	/* Rx can send a break signal */
CANCRY		0x08	/* Receiver can decrypt */
CANLZW		0x10	/* Receiver can uncompress */
CANFC32		0x20	/* Receiver can use 32 bit Frame Check */
ESCCTL		0x40	/* Receiver expects ctl chars to be escaped */
ESC8		0x80	/* Receiver expects 8th bit to be escaped */

为什么要转义?历史原因还是特殊规定?

http://www.sczhlp.com/news/2284/

相关文章:

  • Spring配置说明
  • OpenAI Prompt Caching 详解:如何降低延迟与成本
  • 20250731 棕榈油
  • 题解:UVA12511 Virus
  • NCBI下载SRR数据
  • 2025信创项目管理软件「等保2.0」认证榜单:这7家通过率达到90%!
  • 第二十八天
  • 1小时搭建免费AI知识库,2025年打工人逆袭必备!
  • “数字孪生” 推进超大城市社会治理智能化
  • Win11专业版找不到共享打印机的问题
  • win11正式版为什么打不开磁盘和文件夹的问题
  • 动物免疫抗体制备|多克隆抗体开发服务|免疫原设计与检测平台
  • Gemini 2.5模型重大升级:更智能的AI技术
  • IOC
  • 通过AssemblyLoadContext 卸载清空Roslyn动态编译缓存数据
  • 苹果im虚拟机协议群发系统,苹果imessage推信软件,苹果iMessage自动群发协议–持续更新中...
  • LOJ #6077. 「2017 山东一轮集训 Day7」逆序对
  • 不要傻呵呵等金九银十了!
  • 大纲
  • 浅谈若干类常见数论复杂度的分析方法
  • JAVA
  • java 连接 达梦数据库 新增和查询
  • Ubuntu Desktop 22.04 禁用自动更新 repo
  • 南威软件实习至今感想(入职已有23天) - Lxx
  • Java基础:注释
  • 【SAE出版】2025年固体力学与材料国际学术会议(ICSMM 2025)
  • Intel赛扬J4105/J4125处理器嵌入式无风扇工控机
  • mybatisplus
  • 前端面试复习与准备指南
  • Python文件处理之购物车系统