2016-10-30 3 views
-2

Я создаю простой ftp, который позволяет пользователю запрашивать базовые команды сервера unix (например: cd home/file/) и загружать файлы на сервер и загружать файлы с сервера. Я получил основные команды для работы и печати между клиентом и сервером, но копирование файлов, которые не являются текстом, является проблемой.Как преобразовать двоичный файл в байты?

Мой текущий код функции 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); 
} 

Прямо сейчас, я только пытаясь скопировать файлы правильно, так что пока нет отправки на сервер. С помощью этого кода я могу копировать текстовые файлы в порядке, но другой файл, такой как .o-файл, содержащий 6.0kb, будет скопирован с 8 байтами. Я пытаюсь преобразовать файл в байты (готов к отправке), а затем создать файл из байтов. Я подхожу к этому неправильно? Должен ли я использовать другие средства для этого? Каков правильный способ создания простого FTP?

+0

я вижу, вы закомментирована использование '' sprintf' и strlen' , Эти функции работают только со строками - текстом, которые не являются двоичными данными. Если вы хотите перемещать двоичные данные, вы должны использовать 'memcpy' (или' memmove') вместо 'strcpy'. В старые времена при отправке двоичных данных по RS232, чтобы отличать данные от протокола, одним из способов было разделить каждый байт данных на два куска, посылая каждый как шестнадцатеричный текст. –

+0

Связанный: http://stackoverflow.com/q/1006797/694576 – alk

+0

BTW, FTP * is * a * standard *: https://en.wikipedia.org/wiki/File_Transfer_Protocol Будет ли ваш код подтверждать это? Если нет, лучше не называть это FTP. – alk

ответ

1

Это потому, что ваш буфер заполнен двоичными данными. Двоичные данные могут содержать нулевой символ (\ 0 или 0x00), и он несовместим с strlen, так как strlen остановится при первом значении нуля.

Вы можете попробовать что-то подобное, чтобы вернуть фактическую длину файла:

struct buffer { 
    char *buffer; 
    size_t filelen; 
} 

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

И:

struct buffer * filecpy = convertfile("mtg.jpg"); 
printf("%.*s .... %d\n",filecpy.filelen, filecpy.buffer, filecpy.filelen);