YMODEM协议

  1. 是什么
  2. 关键字定义
  3. 协议格式
  4. 接收方和发送方应实现的处理策略
    1. 共通策略
    2. 接收方策略
    3. 发送方策略
  5. 数据传输

是什么

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int calcrc(char *ptr,   int count)
{
int crc, i;

crc = 0;
while (--count >= 0) {
crc = crc ^ (int)*ptr++ << 8;
for (i = 0; i < 8; ++i)
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
return (crc & 0xFFFF);
}

接收方和发送方应实现的处理策略

共通策略

  • 出错后需要重复尝试10次
  • 协议流程应由接收方驱动
  • 使用CAN或ASCII的^X字符来取消传输

接收方策略

  • 接收方应该有10s超时机制
  • 只要接收到数据开始,接收方使用1s超时机制来接收每个数据,直到该数据包接收完成
  • 同步:
  1. 接收到想要的那个数据包并且没有任何错误后才算接收成功,并返回ACK;
  2. 能够处理两条重复的数据包(ACK丢失引起的问题);
  3. 因为一些特殊原因造成同步出错应终止传输,发送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用一个空格分隔,用于标识传输程序,用一个八进制字符串表示

http://www.textfiles.com/programming/ymodem.txt


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 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" 转载请保留原文链接及作者。

目录