What is the best way to send files over a socket? How is it actually done?
What is the best way to send files over a socket? How is it actually done?
You use some kind of protocol, so that you can prepend information about the file. This can be as elaborate as you want, but at minimum you probably need the length of the file. That can simply be a 4 byte integer. So the recipient reads four bytes into an int, then uses that to determine how much more to read before the file is complete. You could also do something like 4 bytes for the total length, then a null terminated string containing the file name (include that in the length), then the file.
Files on the WWW use the http protocol, which is a text header ending with "\r\n\r\n" (two MS-DOS style newlines).
Last edited by MK27; 11-14-2011 at 11:38 AM.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
I guess i could use something like this to find the size of the file;
I could also use that to keep track of how much data has been sent or read too i assume.Code:fseek(file, 0, SEEK_END); int size = ftell(file);
Why only 4 bytes MK27? Couldnt i use 1MB? Or is that too much?
4 bytes, as an unsigned integer, can encode file sizes upto 4GB.
The 4 bytes is the amount of data that follows, not the data itself.
Like you would send
00 00 00 06 (4 byte length, = 6)
Then
"hello\0"
are the 6 bytes of data.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Yeah, that's a portable way. Using stat() is probably faster, but stat() is *nix specific.
No, write/send and read/recv all return the number of bytes done, so you can keep count that way. The issue is that you cannot count on reading the file all at once, because the underlying tcp/ip layer uses packets and those packets may be delayed. Ie, if you just try and read as much as you can, there is a decent chance you'll only actually get part of the file (issues like this are hard to notice on local loopback, but flare up when you start testing with separate computers, esp. if they are on a large network such the internet).I could also use that to keep track of how much data has been sent or read too i assume.
So you need to know how big the file is in advance, then read it in a loop until until done.
The idea with the 4 byte "header" is it is just an int, altho since ints aren't necessarily 4 bytes, you have to use a more specific type:Why only 4 bytes MK27? Couldnt i use 1MB? Or is that too much?
Now:Code:#include <sys/types.h> int32_t size = (int32_t)ftell(file); // 32 bits == 4 bytes
Make sense? And the recipient:Code:write(sockfd, &size, 4); write(sockfd, filebuffer, (size_t)size)); // or you could read and write the file in chunks adding up to the correct size
Now "len" contains the size of the file to be read in.Code:int32_t len; read(sockfd, &len, 4);
I suppose a u_int32_t (unsigned) is actually better, as Salem implies, since negative numbers make no sense here and an unsigned type has twice the maximum value.
Last edited by MK27; 11-14-2011 at 12:55 PM.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
is there a certain way to declare those unsigned ints?
Some are in <sys/types.h> but I think the most portable place by the standard is <inttypes.h>. That should have int32_t and uint32_t.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge