YMODEMとは、バイナリ転送プロトコルの一種である。XMODEMやMODEM7を発展させたもので、Chuck Forsbergにより開発され、1985年にYMODEMという名称がつけられた。

## 特徴

- 1024バイトもしくは128バイト単位でデータを転送する。
- エラー検出に16ビットのCRC符号を利用する。
- 転送エラーがあった場合、エラーのあったブロックを再送することができる。しかし指定したブロックからやり直す機能はない。
- ファイル名やファイルサイズ、タイムスタンプなどのファイル情報を転送することができる。
- 一度に複数のファイルを転送することができる(バッチ転送)。
- コントロールコードのクォート(置換)処理を行わない。このため、XON/XOFF文字によるフロー制御を行っている場合には不具合をきたす可能性がある。

## 手順

SOH(01h)、STX(02h)、EOT(04h)、ACK(06h)、NAK(15h)、CAN(18h)の6つのコントロールコードと文字 ’C’(43h)、’G’(47h) を使用して通信制御を行い、後述するデータブロックの単位でデータを転送する。

### 基本的な流れ

#### YMODEM

| 受信側 |  | 送信側 |
| --- | --- | --- |
| ’C’(送信要求) | → |  |
|  | ← | ブロック0(1つめのファイル) |
| ACK(肯定応答) | → |  |
| ’C’(送信要求) | → |  |
|  | ← | ブロック1 |
| ACK | → |  |
|  | ← | ブロック2 |
| ACK | → |  |
| (中略) | | |
|  | ← | 最終ブロック |
| ACK | → |  |
|  | ← | EOT(転送終了) |
| NAK | → |  |
|  | ← | EOT |
| ACK | → |  |
| (1ファイル転送終了) | | |
| ’C’(次のファイルを要求) | → |  |
|  | ← | ブロック0(2つめのファイル) |
| (中略) | | |
|  | ← | 最終ブロック(最後のファイル) |
| ACK | → |  |
|  | ← | EOT |
| NAK | → |  |
|  | ← | EOT |
| ACK | → |  |
| ’C’ | → |  |
|  | ← | ブロック0(「全てのファイルを転送終了」) |
| ACK | → |  |
| (通信終了) | | |

1. 受信側が送信要求として ’C’ を送出する。
2. 送信側がファイル情報の入ったデータブロック(ブロック0)を送出する。全てのファイルを転送し終わっている場合はその旨を示すデータブロックを送出する。
3. 受信側はブロック番号、CRC符号を確認し、受信したデータにエラーがないことを確認した後にACKを送出する。全てのファイルの転送が終わっている場合はこれをもって通信を終了する。
4. 受信側は送信要求として ’C’ を送出する。
5. 送信側がデータブロックを送出する。
6. 受信側は、受信したデータにエラーがないことを確認した後にACKを送出する。
7. ACKを受けた送信側は次のデータブロックを送出する。
8. 全てのデータを送出するまで6~7を繰り返す。全てのデータを送出し終わった場合、送信側は送信すべきデータが終了したことを示すEOTを送出する。
9. 受信側がACKを送出する。シングルモードの場合はこれをもって通信を終了する。
10. 手順1に戻る。

#### YMODEM-g

| 受信側 |  | 送信側 |
| --- | --- | --- |
| ’G’(送信要求) | → |  |
|  | ← | ブロック0(1つめのファイル) |
| ’G’ | → |  |
|  | ← | ブロック1 |
|  | ← | ブロック2 |
|  | ← | ブロック3 |
| (中略) | | |
|  | ← | 最終ブロック |
|  | ← | EOT(転送終了) |
| ACK | → |  |
| (1ファイル転送終了) | | |
| ’G’(次のファイルを要求) | → |  |
|  | ← | ブロック0(2つめのファイル) |
| (中略) | | |
|  | ← | 最終ブロック(最後のファイル) |
|  | ← | EOT |
| ACK | → |  |
| ’G’ | → |  |
|  | ← | ブロック0(「全てのファイルを転送終了」) |
| (通信終了) | | |

1. 受信側が送信要求として ’G’ を送出する。
2. 送信側がファイル情報の入ったデータブロック(ブロック0)を送出する。全てのファイルを転送し終わっている場合はその旨を示すデータブロックを送出し、これをもって通信を終了する。
3. 受信側はブロック番号、CRC符号を確認し、受信したデータにエラーがないことを確認した後に、送信要求として ’G’ を送出する。
4. 送信側がデータブロックを次々に送出し、最後にEOTを送出する。
5. 受信側は、受信したデータ全てにエラーがないことを確認した後にACKを送出する。シングルモードの場合はこれをもって通信を終了する。
6. 手順1に戻る。

### エラーが発生した場合

ブロック番号がおかしい、CRC符号とデータの間に矛盾があるなどのエラーが発生した場合、受信側はACKの代わりにNAK(否定応答)を送出する。NAKを受信した送信側は再度同じデータブロックを送出する。ブロック番号を指定して送信を要求する機能はないため、ブロック番号が連続しない場合やYMODEM-gの場合は中断処理(後述)を行うことになる。

### 中断処理

何らかの事情により転送途中に通信を終了させたい場合はCANを送出する。これは受信側・送信側のどちらが送出しても良い。

### データブロック構成

| ヘッダ | データブロック番号 | データブロック番号の1の補数 | データ | CRC符号 |
| --- | --- | --- | --- | --- |
| 8ビット | 8ビット | 8ビット | 1024バイトもしくは128バイト | 16ビット |

### ブロック0

データファイル本体の転送に先立って送出するブロック0のデータ部分には、以下に示すフォーマットでファイル情報をセットする。128バイトもしくは1024バイトに満たない部分はNUL(00h)でパディングする(EOFではない)。また、データ部分を全てNULとすると「続けて送信するファイルはもうない」という意味になる。

|  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ファイル名 | NUL(00h) | ファイルサイズ | 空白(20h) | タイムスタンプ | 空白 | パーミッション | 空白 | シリアルナンバー | NUL(パディング) |
|  | 1バイト |  | 1バイト |  | 1バイト |  | 1バイト |  |
| 128バイトもしくは1024バイト | | | | | | | | | |

## 発展

YMODEMは、ファイル情報を転送できないなどのXMODEMの欠点を克服した。しかし、データブロックを送出するごとにACKを待たなければならないので転送速度が遅い (YMODEM)、転送は速いがエラーが起こっても回復できない (YMODEM-g)、コントロールコードのクォート処理を行わないなどの欠点が残っている。そのため、これらの問題を克服すべく、ZMODEMを翌年にChuck Forsbergが開発した。