0

I used the bottom code to transfer file over socket between 2 clients. When client A wants to send a file to client B, it sends that file to server, after the server receives that file, it sends that file to client B.

My code is used to read then send file:

CFile f;
BOOL p=f.Open(fname,CFile::modeRead);   
char buff[1024];
int y;
int x;
if(!p)
    //print error msg
while(true)
{       
    y=f.Read(buff,1024);
    x=send(s,buff,y,0);     
    if(y<1024)
    {
        f.Close();
        break;
    }           
}   
send(s, "SENT|",6,0);

My code is used to receive then write file:

f.Open(fname,CFile::modeCreate | CFile::modeWrite);

while(true)
{       
    z=recv(sRecSocket,buff,512,0);
    if(z==SOCKET_ERROR)
    {
        break;
    }

    if(strncmp(buff,"SENT|",5)==0)
        break;
    f.Write(buff,z);
}   
f.Close();
send(sRecSocket,"RECV|",6,0);

But when i run my project, sometimes it works well, the file is sent completely to client B, but sometimes does not, the file is sent to client B but the size is 0 byte or smaller than the real size of file. Can somebody tell me the reason? (I'm not good at English, thanks for trying to understand what I'm saying)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    You may want to ensure `y` is *greater* than zero before attempting to send anything. Further, I would advise a packet preamble that includes a length-of-data value. As written you send in 1024-byte chunks and receive in 512-byte chunks, but the `SENT` could be in any arbitrary location once the file data (which is arbitrary in size) is sent. Thus looking for it on 512-byte boundaries will likely not work. – WhozCraig Aug 09 '13 at 11:10

1 Answers1

1

send does not guarantee to send all the data supplied, nor does recv promise to receive all the data available. You have to call them in a loop, adjusting the amount left as you go, checking the error each time, in order to ensure everything is sent or received.

From memory - I always put the loop in these days! - the looping isn't always necessary (I believe it depends on various factors, mostly out of your control), so your code can often appear to work fairly reliably even if you don't have it in.

This is touched on in the MSDN documentation for send:

If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter.

Tom Seddon
  • 2,648
  • 1
  • 19
  • 28