在了解了上一章的知识之后,我们该以哪种协议传输bin文件呢?这里介绍YModem协议,当然可以使用其他的协议传输比如XModem,Modbus 等等。YModem 协议是从 XModem 协议演变而来的,每包数据最多可以达到 1024 字节,是一个非常高效的文件传输协议。

下面是传输过程:
        首先接收方发送字符‘C’,等待发送方接收,如果接收方没有准备好,则接收方持续发送‘C’。

接收方收到 C 后,开始发送第一帧数据:

ymodem协议 tcp ymodem协议依赖库_ymodem协议 tcp

字符:字符为 ASCII 码,指定的几个特定字符。比如 SOH,查询 ASCII 码可以知道是 0x01,它代表该帧有 128byte 数据。如果是 STX 则有 1024byte。

ymodem协议 tcp ymodem协议依赖库_ymodem协议 tcp_02

ymodem协议 tcp ymodem协议依赖库_ymodem协议 tcp_03

编号:编号从 0 开始,根据帧数增加,达到 0xFF 从 0 开始继续递增。比如第一帧发送文件名时的编号为 0x00。程序处理的时候在一开始设置一个变量为 0,每接收一帧数据递增,并且和接收的编号进行对比,如果接收的编号和程序的变量不一致,说明接收错误。编号的反码是对编号进行校验使用的,以确定编号的正确性。比如编号为 0x00,反码为 0xFF。

数据区:固定长度,不足的填充 0x00。可以是 128 字节也可以是 1024 字节,根据帧头字符确定。传输文件名时是完整的文件名,如 “helloword.bin”, 后面填充 0。有的传输软件在传输完文件名这一帧数据后可能会再传输一帧含有文件大小的数据帧(数据区不足还是填充 0),可以根据实际情况测试。

CRC16:只对数据区进行校验,不对前三个字节校验。高字节在前,低字节在后。

接收方接收到第一帧含有文件名的数据帧之后,开始发送 ACK 进行确认应答,并发送字符‘C’,发送方收到‘C’后开始接收第二帧数据,这里包含文件内容的一部分。接收方接收到这帧数据后,发送 ACK 应答,等待第三帧数据,继续 ACK 应答,继续接收……知道接收方接收到所有数据。

当发送方发送完最后一帧数据并接收到 ACK 后,发送 EOT,接收方接收到之后,接收方发送 NAK,发送方继续发送 EOT,这一次接收方发送 ACK。然后接收方再发送‘C’,如果发送方没有下一个文件需要传输,就会发送如下帧:

SOH 00 FF 00~00(共 128 个) CRCH CRCL

接收方接收到后,正式结束此次传输。

ACK、NAK、EOT 的 ASCII 码如下:

ymodem协议 tcp ymodem协议依赖库_文件名_04

ymodem协议 tcp ymodem协议依赖库_ymodem协议 tcp_05

ymodem协议 tcp ymodem协议依赖库_ymodem协议 tcp_06

下面为传输具体过程,以文件大小不足三帧数据为例,黄色为接收方发送的数据。

ymodem协议 tcp ymodem协议依赖库_数据_07

以下为 CRC 校验代码:

ymodem协议 tcp ymodem协议依赖库_数据区_08