Nmodemは、HN「謎の青年失業家」が1991年に発表したバイナリ転送プロトコルの一種。パソコン通信で使用された。通信状態に応じ最大4096バイトの可変長パケットを使用してデータを転送する、ファイル情報を転送できる、一度に複数のファイルを転送できる、リジューム転送ができるなどの特徴を持つ。

対応したホストが少なかった(謎的電網.exe、絵理香K版がサポート。そのほかソースコードが公開されているホストプログラムに組み込んで運用した例もあった)こと、対応したパソコン通信クライアントソフトが皆無であったことなどの事情により、広く使用されることはなかった。

なお、海外で使用された同名のプロトコル "NMODEM" は、XMODEM/CRCを拡張した別物である。

## 特徴

- 最小128バイト、最大4096バイト単位でデータを転送する。
- エラー検出に16ビットのCRC符号を利用する。
- 転送エラーがあった場合、エラーのあった場所から転送をやり直すことができる。
- 途中で通信が途切れてしまった場合でも、後に途切れた場所から転送を再開することができる(リジューム転送)。
- ファイル名やファイルサイズ、タイムスタンプなどのファイル情報を転送することができる。
- 一度に複数のファイルを転送することができる(バッチ転送)。
- コントロールコードのクォート(置換)処理を行わない。

## 手順

EOT、ACK、NAK、CANの4つのコントロールコードと、’0’~’7’、’n’ の9文字を使用して通信制御を行う。

### 基本的な流れ

※各パケットのフォーマットは後述する。

| 受信側 |  | 送信側 |
| --- | --- | --- |
| ヘッダ要求パケット | → |  |
|  | ← | ヘッダパケット(1つめのファイル) |
| ACKパケット(使用するパケット長を指定) | → |  |
|  | ← | 位置情報パケット |
|  | ← | データパケット(1024バイト) |
|  | ← | データパケット(1024バイト) |
| (中略) | | |
|  | ← | データパケット(1024バイト) |
|  | ← | データパケット(2048バイト;エラーが発生しなければ大きなパケットに切り替える) |
|  | ← | データパケット(2048バイト) |
| (中略) | | |
|  | ← | 最終データパケット |
|  | ← | EOT(転送終了) |
| 転送ファイルスキップパケット(次のファイルを要求) | → |  |
| (1ファイル転送終了) | | |
| ヘッダ要求パケット | → |  |
|  | ← | ヘッダパケット(2つめのファイル) |
| (中略) | | |
|  | ← | EOT(最後のファイル) |
| 転送ファイルスキップパケット | → |  |
| (全てのファイルを転送終了) | | |
| ヘッダ要求パケット | → |  |
|  | ← | EOT(「送信すべきファイルはもうない」) |
| (通信終了) | | |

1. 受信側がヘッダ要求パケットを送出する。
2. 送信側がファイル情報の入ったヘッダパケットを送出する。全てのファイルを転送し終わっている場合はEOTを送出し、通信を終了する。
3. 受信側はヘッダパケットにエラーがないことを確認した後にACKパケットを送出する。
4. 送信側が位置情報パケットを送出する。
5. 送信側がACKパケットで指示されたパケット長のデータパケットを次々に送出する。
6. エラーが発生しない場合、8パケットごとに1段階ずつ大きなデータパケットに切り替えて送出を続ける。ファイル末尾など、残りの転送データがデータパケット長に比して小さな場合は、効率の良い小さなパケットに切り替える。
7. 送信側は全てのデータを転送し終わった後、EOTを送出する。
8. 受信側は次のファイルを要求するために転送ファイルスキップパケットを送出する。
9. 手順1に戻る。

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

エラーが発生した場合の例

| 受信側 |  | 送信側 |
| --- | --- | --- |
|  | ← | データパケット(2048バイト) |
|  | ← | データパケット(2048バイト) |
| (途中のデータパケットに何らかのエラーがあった) | | |
| NAKパケット(「xxxxバイト目から再送せよ」) | → |  |
| ACKパケット | → |  |
|  | ← | 位置情報パケット(「xxxxバイト目から送るよ」) |
|  | ← | データパケット(512バイト;小さなパケットに切り替え) |
|  | ← | データパケット(512バイト) |

1. CRC符号とデータの間に矛盾があるなどのエラーが発生した場合、受信側は再送を希望する位置情報を添えたNAKパケットを送出する。
2. 受信側は続けてACKパケットを送出し、データの送信を要求する。回線状態が悪い場合には(このパケットで)使用するパケット長を再指定することもできる。
3. 送信側が位置情報パケットを送出する。
4. 送信側は2段階小さなデータパケットを次々に送出する。8パケット送出してもエラーがない場合は、1段階ずつ大きなパケットに切り替える。

### 中断処理

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

### リジューム転送

| 受信側 |  | 送信側 |
| --- | --- | --- |
| ヘッダ要求パケット | → |  |
|  | ← | ヘッダパケット(1つめのファイル) |
| 位置情報パケット(「xxxxバイト目から転送せよ」) | → |  |
| ACKパケット(使用するパケット長を指定) | → |  |
|  | ← | 位置情報パケット(「xxxxバイト目から送るよ」) |
|  | ← | データパケット(1024バイト) |
|  | ← | データパケット(1024バイト) |

何らかの事情により転送途中に通信が途切れてしまった場合でも、次回接続時に途切れた場所から転送をやり直すことができる。この場合、受信側は通信開始時のACKパケットに先立って位置情報パケットを送出し、転送開始位置を指定する。

### ファイルスキップ

| 受信側 |  | 送信側 |
| --- | --- | --- |
| ヘッダ要求パケット | → |  |
|  | ← | ヘッダパケット(1つめのファイル) |
| 転送ファイルスキップパケット(「そのファイルは送信しなくて良い」) | → |  |
| ヘッダ要求パケット(次のファイルの情報を要求) | → |  |

既に同じファイルが手元にあったなどの場合、受信側は転送ファイルスキップパケットを送出することでファイル転送をスキップすることができる。

## 各種パケットのフォーマット

### 位置情報パケット

データオフセットは128バイト単位で指定し、ビッグエンディアンでセットする。具体的には

とすると、1280バイト目という意味になる。

### ヘッダ要求パケット

もしくは

上記の2種類が定義されている。どちらを使用しても良い。

### ACKパケット

|  |  |  |  |
| --- | --- | --- | --- |
| ACK | 最低パケットサイズ | 最高パケットサイズ | 送信開始時のパケットサイズ |
| 1バイト | 1バイト | 1バイト | 1バイト |

ACKパケットは送信開始合図であるとともに、使用するパケットサイズを指定する目的にも使用する。パケットサイズは ’2’~’7’ の文字で表し、以下のように定義されている。

### NAKパケット

NAKパケットは再送要求であるとともに、再送位置を指定する目的にも使用する。再送要求位置のフォーマットは位置情報パケットのデータオフセットと同じ。再送要求位置を ffh,ffh,ffh とするとヘッダ要求パケットになるので注意が必要。