バイナリファイルを転送するには?

解決


ヨシ  2006-09-14 10:12:58  No: 63017  IP: 192.*.*.*

9/8に質問した↓の続きです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200609/06090018.txt

バイナリファイルの転送がうまくいっていると思っていたのですが、
実際はうまくいっていないようなので、どなたかアドバイス宜しくお願いします。

【やろうとしたこと】
シリアル通信を使って、パソコンAからBにバイナリファイルを転送する。
Bではハイパーターミナルの「テキストのキャプチャ」を使う。
そのとき、
パターン1・・1byte読んで1byte書き込む
パターン2・・パターン1では転送速度が遅くなるので、バッファに318byte
読み込んで318byte書き込む


【結果】
送信ファイルと受信ファイルを比較すると、ファイルの中身はパッと見は一緒。
でもじっくり検証すると、中身もバイト数も違う。

送162196byte
受162253byte

自分でもいろいろ調べてみてるのですが。。
根本的にやりかたが違っているのでしょうか。。

行き詰ってしまったので、どなたかご教授宜しくお願いいたします。

ソース
---------------------------------------------------------------------
        hComm = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 
                                                                0, NULL, OPEN_EXISTING,
                                                                FILE_ATTRIBUTE_NORMAL, NULL);
        //COM通信パラメータを格納しているDCB構造体を設定する。
        DCB lpDCB;
        GetCommState(hComm, &lpDCB);

        lpDCB.DCBlength = sizeof(DCB);
        lpDCB.BaudRate = 9600;
        lpDCB.Parity = NOPARITY;
        lpDCB.StopBits = ONESTOPBIT;
        lpDCB.fParity = FALSE;
        lpDCB.fBinary = TRUE; 
        lpDCB.ByteSize = 8;
---------------------------------------------------------------------
        FILE *fi;
        DWORD dw;
        unsigned char charbuf;
        unsigned char charbuf2[318];
        int a[16];

        if ((fi = fopen("hoge.hoge", "rb")) == NULL) {
                AfxMessageBox("Cannot open input file");
                return;
        }

        /*ヘッダ部の読み込み*/
        /*前回の質問の通り、データ部の総バイト数がわかる。*/
        for(int i=0; i < 16;i++){
                fread(&charbuf, 1, 1, fi);
                a[i] = charbuf;
                WriteFile(hComm,&charbuf,1,&dw,0);
        }

        int count = 0,size = 0;
        
        /*パターン1*/
        /*ファイルの書き込み*/
        for(int i = 0; i < (a[4]*256+a[5])*(a[6]*256+a[7]); i++){
                size = fread(&charbuf, 1, 1, fi);
                WriteFile(hComm,&charbuf,size,&dw,0);
        }
        
//      /*パターン2*/  
//      /*ファイルの書き込み*/  
//      for(int i = 0; i < (a[4]*256+a[5])*(a[6]*256+a[7])/318; i++){
//              size = fread(charbuf2, 1, 318, fi);
//              WriteFile(hComm,charbuf2,318,&dw,0);
//      }
        
        AfxMessageBox("転送終了しました。");

        fclose(fi);
        return;
---------------------------------------------------------------------

編集 削除
dairygoods  2006-09-14 10:29:22  No: 63018  IP: 192.*.*.*

> Bではハイパーターミナルの「テキストのキャプチャ」を使う。

ということは、書き込む側はテキストモードでファイルを開いているわけで、
0x13 が 0x11 0x13 に置き換わってしまうと思います。

ハイパーターミナルにバイナリを受信する機能はありませんか?

編集 削除
ヨシ  2006-09-14 10:36:21  No: 63019  IP: 192.*.*.*

ご回答ありがとうございます。

ハイパーターミナルにはバイナリ受信機能はないのですが、
何か方法はあるのでしょうか?

あと、パターン1とパターン2、どちらの方法でもいけそうでしょうか?
いろいろ調べていて、「fseek」や「 ftell」を使わないといけないのかなーと今考えていたのですが。。

編集 削除
dairygoods  2006-09-14 13:32:39  No: 63020  IP: 192.*.*.*

> ハイパーターミナルにはバイナリ受信機能はないのですが、
> 何か方法はあるのでしょうか?

もし、そのツールがテキストでしか出力できないのでしたら、
そのツールを使う限りは、何も対処できないと思います。


> あと、パターン1とパターン2、どちらの方法でもいけそうでしょうか?

何バイトずつ読み書きするかは動作には何の影響もありません。

(しかし、パターン2のコード自体には問題があります。
  総データ長が318で割り切れないと読みこぼしますし、
  WriteFile の第三引数が固定なのもまずいです。)

編集 削除
ヨシ  2006-09-14 14:33:07  No: 63021  IP: 192.*.*.*

わかりました。
もう少し考えてやってみて、また報告します。

また、何かアドバイス等ありましたら、随時宜しくお願いいたします。

編集 削除
ヨシ  2006-09-18 10:11:26  No: 63022  IP: 192.*.*.*

バイナリの受信機能をもつツールを入手することができました。
それで確認したら送信ファイルと受信ファイルが相違ないことを確認できました。

また、パターン2の第三引数は次のように戻り値を指定することにして対処しました。
size = fread(charbuf2, 1, 318, fi);
WriteFile(hComm,charbuf2,size,&dw,0);

ご教授ありがとうございました。

編集 削除