ZMODEM通信の内部動作について
フィードバックありがとうございます。 Tera TermがZMODEMの仕様書違反をしているならば、それはバグですので、Tera Term側を 修正するのが筋だと思います。 しかし、ZMODEMプロトコルは原作者が実装したので、よく知らないところではあるので教えてください。
・ZACKにオフセット情報を含ませるようにすること
これは、ZSendACK() の ZStoHdr() で、第2引数に zv->Pos を指定すればよいでしょうか?
・続けて送るZRPOSを送信しないようにする
これはどのような修正をすればよいでしょうか?
素早い返答に感激です。ありがとうございます。 おっしゃる通り、ZACKにオフセット情報を含ませるには、ZStoHdr(zv,zv->Pos);とするだけでいいはずです。続くZRPOSについてですが、すみません。これは私の勘違いだったかもしれません。 ZSendACKの最後にFTSetTimeOut(fv,zv->TimeOut);としているのですが、これの意図する所は、ZACKを送信したあとに、対向のデータ送信がタイムアウトした時に、ZRPOSを再送するという意図なのかもしれません。
また、原作者の意図がわからない以上、ZRPOSについての部分に手を加えるのは、もしかすると他の問題を誘発させてしまうかもしれません。ZMODEMといっても、内部実装は様々でしょうし、 他のターミナルソフトとの十分な実績があるTera Termですから、それに対応する処置なのかもしれません。そこで、私の提案としては、ZACKだけの修正を行うということです。恐らくですが、 ZACKのオフセットが0であることを前提としているような実装を他のソフトがしているというのは考えにくいと思います。これなら、ZACKという、ヘッダータイプだけをみている場合でも、オフセットを確認して いる場合でもどちらにも対応できます。またZRPOSについては、ZRPOSの送受信のタイミングにもよりますが、概ねZACKと同じオフセットが含まれることになりますし、オフセットに誤差があっても、 ZMODEMプロトコルで吸収できる範囲内におさまるはずです。
上記提案、ご検討くださいますよう、よろしくお願いします。
プロトコルのデータフローも実装もあまりよく分かっていないのですが...
ZSendACK を呼んでいるのが ZSINIT の返事をするときだけなので、ここで必ず 0 を返すという動作はおかしくないような気がします。しかし ZCheckData 内の ZCRCQ, ZCRCW に応答しているところで ZStoHdr を呼ばずに ZShHdr(zv, ZACK) しており、この実装で必ずオフセットが 0 として送信されるのかあるいは ZSendDataHdr でセットされているので正しいオフセットを送信しているのか、という実際の動作が気になります。
はじめにお詫びします。私の確認不足でした。
確かに、 ZCheckData 内の ZCRCQ, ZCRCWの応答に対してはZSendACKを呼ばずに、直接ZshHdrを呼び出しているので、ZACKが常に0というわけではないようです。 実際にこちらで、1024バイトのパケットにZCRCQとZCRCWをつけて送信後、受信したZACKのオフセットをみると、1024が格納されていました。 ZSendACKで0が指定されているからと、早合点していました。チケットを書く前に実際の値を確認してみるべきでした。
yutakaponさん、mayaさん、お手数をかけさせてすみませんでした。また、的確な解答ありがとうございました。
damumeta への返信
はじめにお詫びします。私の確認不足でした。 確かに、 ZCheckData 内の ZCRCQ, ZCRCWの応答に対してはZSendACKを呼ばずに、直接ZshHdrを呼び出しているので、ZACKが常に0というわけではないようです。 実際にこちらで、1024バイトのパケットにZCRCQとZCRCWをつけて送信後、受信したZACKのオフセットをみると、1024が格納されていました。 ZSendACKで0が指定されているからと、早合点していました。チケットを書く前に実際の値を確認してみるべきでした。 yutakaponさん、mayaさん、お手数をかけさせてすみませんでした。また、的確な解答ありがとうございました。
つまるところ、Tera Term側の修正は不要になったということでしょうか?
はい。修正は不要です。
はじめまして。組込み機器向けにZMODEMプロトコルを実装しているものです。
PCとの通信も前提としてまして、第一に頻繁に使用するTera Termとの通信精度は重視しています。ただ、Tera Termのzmodem.cのソースコードを拝見させて いただいた所、若干ZMODEMプロトコル本来の振る舞いと異なる所がありました。 ZACKというヘッダパケットがあるのですが、ZMODEMプロトコルでは、ZACKは内部に受信したファイルのオフセット情報を含むことになっています。しかしTera Termの 実装では常にオフセット0としているようです。ZACK受信時にはZACKのオフセットを解析しているようですが、送信時は常に0指定です。そして、ZACK後に続けてZRPOSと うヘッダ(これにもファイルオフセットを含みます)を送信しているようです。 概ねこれでも問題ないのですが、送信側にスライディングウインドウを実装しようとした場合、データパケット終端にZCRCWまたはZCRCQという、受信側のZACKを待つ制御 コードを添付します。そして受信したZACKのオフセット情報をみて、送信側のオフセットと照合し、送信データをシークするというのが基本的な動作です。そこに、常にオフ セット0のZACKと、オフセットを含むZRPOSが連続して送信されてくる為、データの整合性が保証できなくなってしまいます。
Tera Termを対向とする場合だけ特別扱いすることも可能ですが、できればそういった方法は避けたいと考えています。ZACKにオフセット情報を含ませるようにすることと、 続けて送るZRPOSを送信しないように変更していただくことは可能でしょうか?