protocol.ymodem

XMODEM/YMODEM 协议实现。

XMODEM 和 YMODEM 协议族紧密相关。该模块同时实现两者,而具体所用的协议由入口点和功能协商所决定。

exception glasgow.protocol.ymodem.YModemError(message)

XMODEM/YMODEM 通信错误。

class glasgow.protocol.ymodem.YModemTransport

抽象 XMODEM/YMODEM 传输层。

abstractmethod async recv(length: int) → bytes

接收 length 个字节。

可以被安全地取消。

abstractmethod async send(data: bytes)

发送 data 并排空缓冲区。

abstractmethod async purge()

清除接收缓冲区中的所有数据。

enum glasgow.protocol.ymodem.YModemHeader(value)

XMODEM/YMODEM 包头。

成员类型:

bytes

合法的值如下:

SOH = <YModemHeader.SOH: 0x01>

128 个字节的数据。

STX = <YModemHeader.STX: 0x02>

1024 个字节的数据。

EOT = <YModemHeader.EOT: 0x04>

传输结束。

ACK = <YModemHeader.ACK: 0x06>

确认。

NAK = <YModemHeader.NAK: 0x15>

负面确认。

CAN = <YModemHeader.CAN: 0x18>

取消。

C = <YModemHeader.C: 0x43>

使用 XMODEM-CRC。

K = <YModemHeader.K: 0x4b>

使用 XMODEM-1K(包含 XMODEM-CRC)

该 Enum 及其成员还有如下的方法:

packet() → YModemPacket

创建一个 XMODEM/YMODEM 控制包。

enum glasgow.protocol.ymodem.YModemVariant(value)

XMODEM/YMODEM 协议变种。

合法的值如下:

XMODEM = YModemVariant.XMODEM
XMODEM_CRC = YModemVariant.XMODEM_CRC
XMODEM_1K = YModemVariant.XMODEM_1K

该 Enum 及其成员还有如下的方法:

property has_crc16

是否为数据包使用 CRC-16。

对 XMODEM_CRC 和 XMODEM_1K 为 True。

property has_1k

是否使用 1024 字节长的数据包。

对 XMODEM_1K 为 True。

class glasgow.protocol.ymodem.YModemPacket(control: YModemHeader, number: int | None = None, data: bytes | None = None)

抽象的 XMODEM/YMODEM 包

表示一个控制或数据包的内容。

control: YModemHeader

头字节。

number: int | None = None

数据包的包编号。

data: bytes | None = None

数据包的包载荷。

classmethod for_data(*, number: int, data: bytes) → YModemPacket

创建一个 XMODEM/YMODEM 数据包。

抛出:

ValueError -- 如果 len(data) 不是 128 或 1024。

async classmethod recv(transport: YModemTransport, *, variant: YModemVariant) → Self | None

从 transport 接收一个数据包。

从 transport 读取单个 XMODEM/YMODEM 包,并将其返回。如果读到的第一个字节不是一个有效的 YModemControl 头,则返回 None。

抛出:
  • YModemError -- 如果校验和或 CRC-16 错误。

  • Exception -- transport.recv() 引发的任何异常。

async send(transport: YModemTransport, *, variant: YModemVariant)

向 transport 发送一个包。

格式化单个 XMODEM/YMODEM 包,并将其写入 transport。

抛出:

Exception -- transport.send() 引发的任何异常。

class glasgow.protocol.ymodem.YModemFileInfo(*, pathname: bytes, length: int | None = None, modified: int | None = None, mode: int | None = None)

YMODEM 在 0 号块中传输的文件元数据。

pathname: bytes

文件路径名。

路径名的格式没有专门规范,但是它“应当在发送方和接受方的操作系统上都被接受”。路径名在任何情况下都不应包含盘符和反斜杠。推荐但是不强制将路径名转换为小写。

length: int | None = None

文件长度。

如果存在,则应用此字段数据来丢弃最后一个数据块结尾的填充。

modified: int | None = None

修改日期。

如果存在,则此字段表示修改日期,为自 1970-01-01 GMT 以来的秒数。

mode: int | None = None

文件模式。

如果存在,表示此文件发送自一个 Unix 系统,并有该字段所示的模式。

classmethod parse(data: bytes)

解析 YMODEM 元数据。

该元数据解析器会容许相较格式规范有明显的偏差的数据,以此尽量提高兼容性。

抛出:

YModemError -- 如果元数据格式无效。

emit() → bytes

序列化 YMODEM 元数据。

备注

对于 self.modified 和 self.mode 中的每个字段,必须在其前序字段有定义的情况下,该字段才会被序列化。

class glasgow.protocol.ymodem.YModemFile(*, info: YModemFileInfo, data: bytes)

YMODEM 文件表示。

info: YModemFileInfo

YMODEM 文件元数据。

data: bytes

文件数据。

classmethod from_path(path: str | PurePath) → Self

从文件系统读取路径 path 的文件。

备注

meta.pathname 字段仅会被设置为文件名(不含路径,不进行大小写转换)。如果需要不同行为,调用者应修改此字段。

class glasgow.protocol.ymodem.YModemProtocol(transport: YModemTransport, *, logger: Logger = logger, progress: Progress | None = None)

XMODEM/YMODEM 协议处理。

处理包序列化、重传、数据存储。

async recv_single(*, variant=YModemVariant.XMODEM_1K) → bytearray

用 XMODEM 协议接受单个文件。

返回连接起来的每个数据块;返回值会包含最后的填充。

抛出:
  • YModemError -- 如果重传次数超过限制。

  • YModemError -- 如果出现其它协议违例。

  • Exception -- transport.send() 或 transport.recv() 引发的任何异常。

async recv_batch() → list[YModemFile]

用 YMODEM 协议接受一系列文件。

返回接受到的文件组成的列表,每个文件的数据裁切去掉填充。

抛出:
  • YModemError -- 如果 YMODEM 元数据的格式错误。

  • YModemError -- 如果重传次数超过限制。

  • YModemError -- 如果出现其它协议违例。

  • Exception -- transport.send() 或 transport.recv() 引发的任何异常。

async send_single(file_data: bytearray)

用 XMODEM 协议发送单个文件。

最后一个块会被以 ASCII 0x1A (SUB) 填充至 128 字节的块边界。

抛出:
  • YModemError -- 如果出现协议违例。

  • Exception -- transport.send() 或 transport.recv() 引发的任何异常。

async send_batch(files: list[YModemFile])

用 YMODEM 协议发送一系列文件。

见 send_single() 的备注。

抛出:
  • YModemError -- 如果出现协议违例。

  • Exception -- transport.send() 或 transport.recv() 引发的任何异常。