YMODEM

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

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

 YMODEMの種類 
 YMODEM XMODEM/1kにファイル情報の転送、複数ファイルの転送機能を追加したもの。単に "YMODEM" と称した場合は通常これを指す。
 YMODEM-g 受信側の応答を求めずに次々とデータを転送するYMODEM。高速転送が可能だが、エラーが起こっても回復することはできない。
 YMODEM(-g)シングルモード 複数ファイルの転送機能を持たないYMODEMであり、本来の仕様には存在しないモード。日本で単に "YMODEM" と称した場合はこちらを指す場合もあり、その際複数ファイルを転送可能なYMODEM(-g)は "YMODEM(-g)/Batch" などと称され区別される。

 手順 
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 → （通信終了）

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

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

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

 エラーが発生した場合 
+ ブロック8でエラーが発生した場合の例 受信側 送信側 ← ブロック7 ACK → ← ブロック8 （ブロック8に何らかのエラーがあった） NAK（再送要求） → ← ブロック8（再度同じブロックを送出） ACK → ← ブロック9

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

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

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

 ヘッダ データのサイズを表す。1024バイトであればSTX、128バイトであればSOHをセットする。送信するデータに最適なサイズを使用する。
 データブロック番号 ブロック番号をセットする。0から開始して1ずつカウントアップし、255の次は0になる。
 データブロック番号の1の補数 ブロック番号の1の補数（全ビットを反転させたもの）をセットする。
 データ 送信するデータを1024バイトもしくは128バイト単位でセットする。送信するデータが1024バイトもしくは128バイトに満たない場合はEOF(1Ah)でパディングする（空いた部分を埋める）。
 CRC符号 16ビットのCRC符号をビッグエンディアンでセットする。

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

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

 ファイル名 ファイル名をセットする。
 ファイルサイズ ファイルの大きさを十進ASCII文字列でセットする。
 タイムスタンプ ファイルの更新日時をグリニッジ標準時1970年1月1日からの経過秒数に直し、八進ASCII文字列でセットする。
 パーミッション UNIXではこれを八進ASCII文字列でセットする。必要のない場合やUNIX以外ではNULをセットする。
 シリアルナンバー UNIXではこれを八進ASCII文字列でセットする。必要のない場合やUNIX以外ではNULをセットする。

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

 関連項目 
バイナリ転送プロトコル
XMODEM
ZMODEM

 外部リンク 
XMODEM/YMODEM Protocol Reference

Category:パソコン通信
Category:ファイル転送プロトコル