csocketspdffreadsendto

How to read and transfer PDF files in C with fread()


I'm writing TFTP client in C. So far I had no problem with reading file into buffers(512 B) and transfer it to the server. However I'm struggling to read files like PDF that contains binary data.

        size_t nmemb = fread(data_buf, sizeof(char), 512, fp);
        ...
        /* Create DATA packet and send it to TFTP server */ 
        count = sprintf(message, "%c%c%c%c%s", 0, DATA, 0, block_number, data_buf); 
        sendto(sock, message, count, 0, (const struct sockaddr *)&server, sizeof(server));

I tested this with printing every buffer separately: printf("%d: %s\n", nmemb, data_buf); Looks like nmemb is always 512, which is correct, but printf() stops printing data when it gets to a first NULL byte, which I'm sure represents the end of a given string(buffer).

Buffer data within DATA packet that is sent through a TFTP protocol are also cut off at first occurrence of NULL byte - I tested this in Wireshark.

Is there a way to fix this problem by using some alternative to fread() or changing a way packet is sent through socket? Thanks for any answer.


Solution

  • You can't use the printf family of functions for this since they stop when \0 is encountered.

    First approach: Use memcpy:

    size_t nmemb = fread(data_buf, 1, sizeof data_buf, fp);
    
    char message[sizeof data_buf + 4]; // presumably
    
    count = sprintf(message, "%c%c%c%c", 0, DATA, 0, block_number);
    memcpy(message + count, data_buf, nmemb);
    

    Second approach (the preferred way): Avoid the copying and fread directly into the buffer you'll later send:

    char message[512 + 4] = {0, DATA, 0, block_number};
    size_t nmemb = fread(message + 4, 1, 512, fp);
    sendto(sock, message, nmemb + 4, 0, (const struct sockaddr *)&server, sizeof(server))
    

    Note: sizeof(char) is always 1. It can't be anything else.