Lingxiao Lingxiao - 1 month ago 10
C Question

C Socket file transfer corrupted data

According to this solution to send out an image through TCP. Since the code is very elegant compared to other ways and both image and file are data, I believe that we can use almost the same code to send out a file.

So if I want to send a file from a client to a server.

On the client side


  1. get file size

  2. send file size
    // Above steps will always work, so I will only show code after here

  3. read file content into a buffer

    char buf[size];
    read(fs,buf,size);

  4. send the buffer

    int bytes = 0;
    for (uint i = 0;i<size;i+=bytes)
    {
    if ((bytes = send(sock,buf+i,size-i,0))<0)
    {
    fprintf(stderr,"Can not send file\n");
    close(fd);
    return false;
    }
    fprintf(stderr,"bytes write = %d\n",bytes);
    }



And on the server side


  1. recv file size

  2. recv stuff into a buffer with size from step 1

    char buf[size];
    int bytes=0;
    for (uint i = 0;i<size;i+=bytes)
    {
    if ((bytes = recv(sock,buf+i,size-i,0))<0)
    {
    fprintf(stderr,"Can not receive file\n");
    return false;
    }
    fprintf(stderr,"bytes read = %d\n",bytes);
    }

  3. write buffer to a file

    fwrite(buf,sizeof(char),size,fs);



This code will compile and run.

When I send out an cpp binary file(24k) from client to server, since both client and server are on the same machine (OS X), this binary file will be received and can be executed.

But if the server forward the file back to the client, and client forward this file back to the server multiple times, this binary file will be corrupted. But the number of bytes sent and number of bytes received are the same, and the file size is still 24k.

I am wondering what is going wrong here.

Is this an OS bug?

Thanks,

Answer

If both client and server are in the same folder, then in this case it is just like copying and pasting a file.

So when client send out a file, it will

  1. open file
  2. get file name/size + send name/size + send data
  3. close file

On the server side,

  1. get file name/size
  2. open the same file again
  3. get file content
  4. close file

So the problem will occur on step 2 by causing a race condition.