2016-10-30 7 views
-2

私はUnixサーバの基本的なコマンド(例えば:cd home/file/)を聞き、サーバにファイルをアップロードし、サーバからファイルをダウンロードすることができる簡単なftpを構築しています。クライアントとサーバーの間で作業して印刷する基本的なコマンドを手に入れましたが、テキストではないファイルをコピーすることは困難です。どのようにバイナリファイルをバイトに変換しますか?

次のようget機能のための私の現在のコードは次のとおりです。

Cli6.c

else if (strcmp(tokens[0], "get") == 0) { 
     char *filecpy = convertfile("mtg.jpg"); 
        printf("%s .... %d\n", filecpy, strlen(filecpy)); 
    } 

FTP.c

char *convertfile(const char *filename) { 
    FILE *fileptr; 
    char *buffer; 
    long filen; 
    size_t result; 
      
    fileptr = fopen(filename, "rb"); 
      
    fseek(fileptr, 0, SEEK_END); 
    filen = ftell(fileptr); 
    rewind(fileptr); 
      
    printf("File size: %d\n", filen); 
      
    buffer = (char *)malloc(filen + 1); // this is only allocating 8bytes 
      
    fread(buffer,filen, 1,fileptr); 
    printf("Buffer: %s\n", buffer); 
    close(fileptr); 
      
      
    /* 
    char *c; 
    char *buffer; 
    fileptr = fopen(filename, "rb"); 
    while (c != EOF) { 
        fread(&c, (size_t)1, (size_t)1, fileptr); 
        buffer[c]++; 
        c = fgetc(fileptr); 
        sprintf(buffer[strlen(buffer)], "%c", c); 
    } 
    close(fileptr); 
    */          
      
    return buffer; 
} 
  
//convert bytes to file 
void convertbytes(const char *buffer, const char *filename) { 
    FILE *fileptr; 
    printf("%s .... %d\n", buffer, strlen(buffer)); 
    fileptr = fopen(filename, "wb"); 
    //for (int i = 0; i < sizeof(buffer); i++) { 
    fwrite(buffer, 1, strlen(buffer), fileptr); 
        //printf("%c :: %d\n", buffer[i], i); 
    //} 
      
    close(fileptr); 
} 

、私だけですファイルを正しくコピーしようとしているため、まだサーバーに送信していません。このコードでは、テキストファイルを正常にコピーできますが、6.0kbを含む.oファイルなどの別のファイルは8バイトでコピーされます。ファイルをバイトに変換しようとしています(どこかで送信する準備ができています)。私はこの間違いに近づいていますか?私はこれを行うために他の手段を使用すべきでしょうか?シンプルなFTPを構築する正しい方法は何ですか?

+0

struct buffer { char *buffer; size_t filelen; } struct buffer *convertfile(const char *filename) { ... } 

とを。これらの関数は文字列(バイナリデータではないテキスト)でのみ機能します。バイナリデータを移動させたい場合は、 'strcpy'の代わりに' memcpy'(または 'memmove')を使わなければなりません。 RS232でバイナリデータを送信する昔、プロトコルとデータを区別するために、各データバイトを2つのニブルに分割し、それぞれを16進テキストとして送信する方法がありました。 –

+0

関連:http://stackoverflow.com/q/1006797/694576 – alk

+0

申し訳ございませんが、FTP *は* a *標準*です:https://en.wikipedia.org/wiki/File_Transfer_Protocolあなたのコードはこれを確認しますか?そうでない場合は、FTPと呼んではいけません。 – alk

答えて

1

これは、バッファがバイナリデータで満たされているためです。 バイナリデータにはヌル文字(\ 0または0x00)を含めることができ、strlenは最初のヌル文字で停止するため、strlenと互換性がありません。

あなたは、実際のファイルのな長さを返すためにそのような何かを試すことができます:私はあなたがsprintf`と `strlen``の使用をコメントアウトしている参照

struct buffer * filecpy = convertfile("mtg.jpg"); 
printf("%.*s .... %d\n",filecpy.filelen, filecpy.buffer, filecpy.filelen); 
関連する問題