PDA

View Full Version : help! transferring binary files on tcp connection


venturasan
04-11-2003, 02:24 PM
Can anyone help me?
I have a question as to how to receive and send binary files across a tcp socket (i am workin in C of course).
i have associated the socket stream with 2 files, one is for sending and one is for receiving.
e.g
receive = fdopen (sock, "rb");
where sock is my socket.

the binary files are transferred in blocks of up to 128 characters.
Each block commences with the size, specified as a single byte, followed by bytes of file data. may be any value in the range 0 to 128 inclusive.
The end of file is indicated by a null (byte value 0, control-@) occurring instead of a data block.

i'm trying to use fread to read my receive file but i'm getting more bytes than i should store in my file.
any ideas? :oops: hope u can understand my code

here's my code:
FILE *tmpf; //file to save data to...
int i, j, ret, size;
int t =0;
char szBuf[128];
char c;
tmpf = fopen(av[q], "wb"); //make new file for writing from command line

// Receive data from the client
j=1;
while (j >0)
{
memset(szBuf, 0, sizeof(szBuf));// clear buffer
ret = fread(szBuf,1, 1, receive); //reading from socket

i =0;
j= ret;
while (ret > i)
{
c = szBuf[i];
i++;
if (c != NULL)
{
putc(c,tmpf);
}
}

RobSeace
04-11-2003, 09:10 PM
Well, that seems a strange way to do things... Why split it into
128-byte blocks, and prefix each one with a header? Why not just
put one header at the beginning giving the full file size, then just
dump all of the raw data after that? The client will still know exactly
how much it has to read, since it'll know the full file size as well as
how much it has already read... Also, you don't need/want any kind
of EOF marker... A null char is perfectly valid to find inside a binary
file, so you don't want to be treating that as an EOF condition... And,
if you know the full size of the file, you don't need any marker anyway,
since you know when you've reached the end...

But, that code looks weird... It looks like you're only reading a single
byte into your buffer, even though you're trying to loop through it as
if you read more...

venturasan
04-12-2003, 02:01 AM
thanks for the reply :)
yeah it is a bit strange the way the blocks are handled, although the null is used to signal end of network transmission only and is not actually stored in the file....

i was just wondering how can i read in just the first byte of the data which contains the size so that i know how much data will be coming after? (this is because the server will be sending blocks of different sizes)
thanks for any help,
me a fresh newbie at network programming... :?

RobSeace
04-12-2003, 07:39 PM
But, if you're transfering binary files, they might contain null characters
themselves... So, you don't want to just be checking for a null char
anywhere in the data, and treating it as an EOF marker, since it might
not be one... But, I think I see what you're saying now: the null char
would be the leading size char in front of one of these blocks... So, the
real EOF condition would be a block size of 0... That makes sense, I
suppose... (Though, I still don't see the need for all these tiny blocks,
rather than just one up-front size for the entire amount of data... *shrug*)

And, as for how to read the size char, it seems pretty simple... Just
something like:


uchar size;
char block[255];

read (sockfd, &size, 1);
if (size == 0)
/* there's your 'EOF' condition */
else
read (sockfd, block, size);


I used an unsigned char and allowed for blocks upto 255 chars, but if
you're certain they can be no more than 127 in length, you could use a
signed char, I suppose... (You'd then want to treat negatives as some
kind of error, I guess..) Also, I just used normal read(), but you can
translate it to stdio-based fread() or whatever, easily enough...

venturasan
04-14-2003, 02:12 AM
alright thanks for your reply robseace,
i'll give it a go :D