YMODEM协议
是什么
YMODEM是发源于XMODEM/CRC的早期应用在调制解调器上的协议,它的产生是为了解决XMODEM协议的如下缺点:
- 单次传输字节少
- 8bit校验影响了传输的可靠性
- 传输文件过程中可能最多累计会产生127byte的无效字节的传输
- 传文件会丢失文件的修改日期信息
正因为XMODEM协议有如上这些缺点,所以,YMODEM在此基础上,优化解决了以上这些缺点,并且尽可能地使得协议变得更简单。
如下这些公共域程序中已经支持YMODEM协议,YAM (CP/M),YAM(CP/M-86), YAM(CCPM-86), IMP (CP/M),KMD (CP/M), MODEM76.ASM (CP/M),rb/sb (Unix, VMS, Berkeley Unix, Venix, Xenix, Coherent, IDRIS, Regulus)和Professional-YAM.1等,
关键字定义
在YMODEM协议中定义了几种关键字,分别代表不同的含义。
Key Words | Value | Description |
---|---|---|
SOH | 0x01 | 协议头(128bytes类型) |
STX | 0x02 | 协议头(1k类型) |
EOT | 0x04 | 传输结束 |
ACK | 0x06 | 接收响应 |
NAK | 0x15 | 失败响应 |
CAN | 0x18 | 取消传输 |
C | 0x43 | 开启文件传输 |
除了以上关键字,还有如下特定功能的符号定义。
Key Words | Value | Description |
---|---|---|
ASCII tabs | 0x09 | 每个tabs符号宽度为8 |
CR/LF | 0x0D/0x0A | 行结束标志 |
CPMEOF(^Z) | 0x1A | 文件结束标志 |
在YMODEM协议中字符定义遵循ASCII码表,因此更多特殊字符定义可参考ASCII码表。
协议格式
上面已经说到了YMODEM协议中会用到的一些符号的定义,下面就描述了YMODEM协议的组成结构究竟是怎样的?
以下是XMODEM协议的定义,
| SOH | blk# | 255 - blk# | 128 bytes data | chsum |
以下是XMODEM/CRC协议的定义,
| SOH | blk# | 255 - blk# | 128 bytes data | CRC-hi | CRC-lo |
以下是YMODEM协议的定义,
| SOH | blk# | 255 - blk# | 128 bytes data | CRC-hi | CRC-lo |
| STX | blk# | 255 - blk# | 1024 bytes data | CRC-hi | CRC-lo |
第一字节
表示协议头,标识一条YMODEM传输协议的起始
第二字节
发送数据的序号,从1开始递增,每次加1,直到到达255后继续递增会循环到0开始。
第三字节
序号的反码
第四字节
这个字节开始封装的是传输的数据128字节或1024字节
最后两个字节
最后的两个字节是校验码。
校验和的计算
校验和采用16位CRC校验,多项式为X^16 + X^12 + X^5 +1,如下是C语言实现的校验算法,
1 | int calcrc(char *ptr, int count) |
接收方和发送方应实现的处理策略
共通策略
- 出错后需要重复尝试10次
- 协议流程应由接收方驱动
- 使用CAN或ASCII的^X字符来取消传输
接收方策略
- 接收方应该有10s超时机制
- 只要接收到数据开始,接收方使用1s超时机制来接收每个数据,直到该数据包接收完成
- 同步:
- 接收到想要的那个数据包并且没有任何错误后才算接收成功,并返回ACK;
- 能够处理两条重复的数据包(ACK丢失引起的问题);
- 因为一些特殊原因造成同步出错应终止传输,发送CAN
发送方策略
- 等待传输开始的这段时间,发送方应该设置一个比较长的超时时间,也可以不设置超时时间
- 文件传输结束应该发送EOT到接收方,直到收到一条ACK响应,否则重复发送
数据传输
首先来看看数据传输过程中的错误处理与恢复过程。
Sender | Receiver |
---|---|
C | |
SOH 01 FE data[128] crc crc | |
ACK | |
SOH 02 FD data[128] crc crc (传输出错) | |
NAK | |
SOH 02 FD data[128] crc crc | |
ACK | |
SOH 03 FC data[128] crc crc | |
(ack数据出错) ACK | |
10s超时 | |
NAK | |
SOH 03 FC data[128] crc crc | |
ACK | |
EOT | |
anything except ack | |
EOT | |
ACK |
下面展示了单个数据包包含1024字节数据的数据包传输的过程。
Sender | Receiver |
---|---|
C | |
STX 01 FE data[1024] crc crc | |
ACK | |
STX 02 FD data[1024] crc crc | |
ACK | |
STX 03 FC data[1000] CPMEOF[24] crc crc | |
ACK | |
EOT | |
ACK |
下面展示了文件的批量传输过程。
Sender | Receiver |
---|---|
C | |
SOH 00 FF “foo.c” data[123] crc crc | |
ACK | |
C | |
STX 01 FE data[1024] crc crc | |
ACK | |
SOH 02 FD data[128] crc crc | |
ACK | |
STX 03 FC data[1000] CPMEOF[24] crc crc | |
ACK | |
EOT | |
NAK | |
EOT | |
ACK | |
C | |
SOH 00 FF NULL[128] crc crc | |
ACK |
在批量传输的时候第一个数据包的序列号就不是从1开始的了,而是从0开始,用来传输将发送文件的文件名,属性等信息,其数据域的填充格式如下所示。
| Pathname | Length | Modification Date | Mode | Serial Number |
- Pathname,是一个字符串,以字符结束符(\0)结束
- Length,是一个表示十进制数的一串字符,用来表示传输的文件有多少字节
- Modification Date,与Length用一个空格分隔,是一个八进制数的一串字符,该数表示距离1970年1月1日的秒数
- Mode,与Modification Date用一个空格分隔,是一个八进制数的一串字符,用以表示文件的类型
- Serial Number,与Mode用一个空格分隔,用于标识传输程序,用一个八进制字符串表示
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com
文章标题:YMODEM协议
本文作者:红尘追风
发布时间:2016-09-17, 20:45:46
原始链接:http://www.micernel.com/2016/09/17/YMODEM%E5%8D%8F%E8%AE%AE/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。