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.
CodePudding user response:
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.