0

1: The server copy the file size into the buffer and send it:

  snprintf(t_buf, 255, "%" PRIu32, fsize);
  if(send(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2: The client receives the file size and put it into fsize:

  if(recv(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0 ,0 ,1);
  }
  fsize = atoi(t_buf);

----------------- The code above makes my program working perfectly!

The problem happens if i write this code instead of the previous one:
1: The server send fsize:

  if(send(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2: The client receives fsize:

  if(recv(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0, 0, 1);
  }

Where uint32_t fsize; and char t_buf[256];.
The problem is that with the first method all work but with the second method the client doesn't receive all file but only a piece of it. What is wrong with this code?
Thanks!

polslinux
  • 1,739
  • 9
  • 34
  • 73

2 Answers2

1

recv(2) doesn't necessarily fill the complete output buffer - it might return fewer bytes depending on how much data is available:

The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.

The return value (when > 0) will be the number of bytes received, so you can call it in a loop if you want to be sure to receive everything.

Alternatively, you could pass the MSG_WAITALL flag:

This flag requests that the operation block until the full request is satisfied. However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or the next data to be received is of a different type than that returned.

So in your case, you could do something like:

ssize_t bytes = recv(f_sockd, &fsize, sizeof(fsize), MSG_WAITALL);

if(bytes == sizeof(fsize))
{
    /* received everything */
}
else
{
    /* something went wrong */
}
James M
  • 18,506
  • 3
  • 48
  • 56
0

Hard to tell without more data.

Could be endianness. You should print out the value of fsize.

Could also be partial return from recv(), as was mentioned in a comment.

unwind
  • 391,730
  • 64
  • 469
  • 606