2015-07-17 7 views
2

Мне нужна помощь в программе, которую я должен создать для школы. Я не знаю точно, как делать чтение и манипулирование данными из файла bin. Файл bin находится в форме заголовка TCP, и мне нужно:Как читать/записывать из файла bin заголовка tcp

  1. Прочитать двоичный файл в структуре и распечатать заголовок.
  2. Создайте ответный заголовок и напишите его в новый файл.
  3. Прочтите двоичный файл ответа и напечатайте заголовок.

Это то, что я до сих пор:

struct tcp 
{ 
    unsigned char sourceport[2]; 
    unsigned char destination[2]; 
    unsigned char sequence[4]; 
    unsigned char ackno[4]; 
    unsigned char other[2]; 
    unsigned char window[2]; 
    unsigned char checksum[2]; 
    unsigned char urgent[2]; 
} my_header; 

int readfile(char filename[]) 
{ 
    FILE *fp; 
    int pointer, i; 
    unsigned char buffer[20]; 
    fp = fopen(filename, "r"); 

    if(!fp){ return 1; } 

    fread(&my_header, sizeof(my_header), 1, fp); 
    i = 0; 
    pointer = 0; 

    while (pointer < 2) 
    { 
     my_header.sourceport[pointer] = buffer[pointer]; 
     pointer++; 
    } 

    while (pointer < 4) 
    { 
     my_header.destination[pointer - 2] = buffer[pointer]; 
     pointer++; 
    } 

    while(pointer < 8) 
    { 
     my_header.sequence[pointer - 4] = buffer[pointer]; 
     pointer++; 
    } 

    while(pointer < 12) 
    { 
     my_header.ackno[pointer - 8] = buffer[pointer]; 
     pointer++; 
    } 

    while(pointer < 14) 
    { 
     my_header.other[pointer - 12] = buffer[pointer]; 
     pointer++; 
    } 
    while(pointer < 16) 
    { 
     my_header.window[pointer - 14] = buffer[pointer]; 
     pointer++; 
    } 

    while(pointer < 18) 
    { 
     my_header.checksum[pointer - 16] = buffer[pointer]; 
     pointer++; 
    } 

    while(pointer < 20) 
    { 
     my_header.urgent[pointer - 18] = buffer[pointer]; 
     pointer++; 
    } 

    fclose(fp); 
    return 0; 
} 

int main(int argc, char* argv) 
{ 
    int check; 
    unsigned char swap[2]; 
    check = readfile("test.bin"); 

    /* Checking for file to read */ 
    if(check == 0) 
    { 
     printf("File successfully read\n"); 
    } 

    /* If file is not found */ 
    if(check == 1) 
    { 
     printf("Cannot open/find file.\n"); 
    } 

    strcpy(swap,my_header.sourceport); 
    strcpy(my_header.sourceport, my_header.destination); 
    strcpy(my_header.destination, swap); 
    writefile("test.bin"); 

    return 0; 
} 

ответ

0

Есть несколько проблем, с вашей readfile функции.

Основная проблема заключается в том, что вы принимаете значения в буфере (которые не назначены) и записываете эти значения мусора в свои поля структуры. Вы делаете адрес my_header вместо buffer.

Кроме того, вы не проверяете возвращаемое значение fread(), так что вы не знаете, завершился ли вызов или если он вернул достаточное количество байтов.

Как оказалось, чтение непосредственно в my_header на самом деле является предпочтительным способом справиться с этим. Предполагая, что чтение было успешным, и поля структуры имеют одинаковый размер и в том же порядке, что и содержимое файла, вам не нужно ничего делать. Структура уже заселена.

Так что ваша функция должна выглядеть следующим образом:

int readfile(char filename[]) 
{ 
    FILE *fp; 
    int bytes_read; 

    fp = fopen(filename, "r"); 
    if (!fp) { 
     perror("fopen failed"); 
     return 1; 
    } 

    bytes_read = fread(&my_header, sizeof(my_header), 1, fp); 
    if (bytes_read == -1) { 
     perror("fread failed"); 
     fclose(fp); 
     return 1; 
    } else if (bytes_read != sizeof(my_header)) { 
     fprintf(stderr, "expected to read %d bytes, actually read %d\n", sizeof(my_header), bytes_read); 
     fclose(fp); 
     return 1; 
    } 

    fclose(fp); 
    return 0; 
} 

Обратите внимание на использование perror печатать подробные сообщения об ошибках для fopen и fread, а также обеспечение для вызова fclose(fp) в случае ошибки после того, как файл был открыт.

Edit:

структура содержит массивы символов, однако они не являются строками, но массивы байтов, так что вы не можете использовать strcpy или другие функции манипулирования строками на них. Однако вы можете использовать memcpy:

memcpy(swap,my_header.sourceport, 2); 
memcpy(my_header.sourceport, my_header.destination, 2); 
memcpy(my_header.destination, swap, 2); 
+0

Хорошо, что имеет смысл, я думал, что я должен был прочитать в целом бен файл первым прямо в массив, а затем разобрать его. Кроме того, как я могу манипулировать массивами в структуре? Я использую их как массивы char, мне нужно использовать strcpy ?. Я просто пытаюсь читать в битах данных. Предположительно из файла bin, который содержит заголовок tcp. – salest

+0

@salest См. Мое редактирование – dbush